static void dissect_HEARTBEAT_VIRTUAL(tvbuff_t *tvb, packet_info *pinfo _U_, gint offset,
                guint8 flags, const guint encoding, int octets_to_next_header, proto_tree *tree,
                guint16 vendor_id _U_, endpoint_guid *guid) {

    /*
    * VIRTUAL_HB:
    *
    * 0...2...........7...............15.............23...............31
    * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    * | VIRTUAL_HB    |X|X|X|X|N|W|V|E| octetsToNextHeader            |
    * +---------------+---------------+---------------+---------------+
    * | EntityId readerId                                             |
    * +---------------+---------------+---------------+---------------+
    * | EntityId writerId                                             |
    * +---------------+---------------+---------------+---------------+
    * | Guid_t virtualGUID (V=0 & N=0)                                |
    * +                                                               +
    * |                                                               |
    * +                                                               +
    * |                                                               |
    * +                                                               +
    * |                                                               |
    * +---------------+---------------+---------------+---------------+
    * | unsigned long numWriters (W=1)                                |
    * +---------------+---------------+---------------+---------------+
    * |                                                               |
    * ~ WriterVirtualHBList writerVirtualHBList                       ~
    * |                                                               |
    * +---------------+---------------+---------------+---------------+
    * | unsigned long count                                           |
    * +---------------+---------------+---------------+---------------+

    * WRITER_VIRTUAL_HB:
    *
    * 0...2...........7...............15.............23...............31
    * +---------------+---------------+---------------+---------------+
    * | EntityId writerId (W=1)                                       |
    * +---------------+---------------+---------------+---------------+
    * | unsigned long numVirtualGUIDs (N=0)                           |
    * +---------------+---------------+---------------+---------------+
    * |                                                               |
    * ~ VirtualGUIDHBList virtualGUIDHBList                           ~
    * |                                                               |
    * +---------------+---------------+---------------+---------------+
    *
    * VIRTUAL_GUID_HB:
    *
    * 0...2...........7...............15.............23...............31
    * +---------------+---------------+---------------+---------------+
    * | Guid_t virtualGUID (V=1)                                      |
    * +                                                               +
    * |                                                               |
    * +                                                               +
    * |                                                               |
    * +                                                               +
    * |                                                               |
    * +---------------+---------------+---------------+---------------+
    * |                                                               |
    * + SequenceNumber firstVirtualSN                                 +
    * |                                                               |
    * +---------------+---------------+---------------+---------------+
    * |                                                               |
    * + SequenceNumber lastVirtualSN                                  +
    * |                                                               |
    * +---------------+---------------+---------------+---------------+
    * |                                                               |
    * + SequenceNumber firstRTPSSN                                    +
    * |                                                               |
    * +---------------+---------------+---------------+---------------+
    * |                                                               |
    * + SequenceNumber lastRTPSSN                                     +
    * |                                                               |
    * +---------------+---------------+---------------+---------------+
    */

    guint32 num_writers, num_virtual_guids, wid;
    gint writer_id_offset, virtual_guid_offset = 0, old_offset;
    proto_item *octet_item, *ti;

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

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

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

    /* 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);
    writer_id_offset = offset;
    offset += 4;
    guid->entity_id = wid;
    guid->fields_present |= GUID_HAS_ENTITY_ID;
    rtps_util_topic_info_add_tree(tree, tvb, offset, guid);

    /* virtualGUID */
    if (!(flags & FLAG_VIRTUAL_HEARTBEAT_V) && !(flags & FLAG_VIRTUAL_HEARTBEAT_N)) {
      /*rtps_util_add_generic_guid(tree,
      tvb,
      offset,
      "virtualGUID",
      buffer,
      MAX_GUID_SIZE);*/
      virtual_guid_offset = offset;
      offset += 16;
    }

    /* num_writers */
    ti = proto_tree_add_item(tree, hf_rtps_virtual_heartbeat_num_writers, tvb,
        offset, 4, encoding);
    if (flags & FLAG_VIRTUAL_HEARTBEAT_W) {
      num_writers = tvb_get_guint32(tvb, offset, encoding);
      offset += 4;
    } else {
      proto_item_set_text(ti, "numWriters: 1");
      num_writers = 1;
    }

    {
      /* Deserialize Writers */
      proto_tree *sil_tree_writer_list;
      guint32 current_writer_index;

      /** Writer list **/
      sil_tree_writer_list = proto_tree_add_subtree_format(tree, tvb, offset, -1,
           ett_rtps_writer_heartbeat_virtual_list, NULL, "Writer List");

      current_writer_index = 0;

      while (current_writer_index < num_writers) {
        proto_tree *sil_tree_writer;
        sil_tree_writer = proto_tree_add_subtree_format(sil_tree_writer_list, tvb, offset, -1,
           ett_rtps_writer_heartbeat_virtual, NULL, "writer[%d]", current_writer_index);

        if (num_writers == 1) {
          old_offset = offset;
          offset = writer_id_offset;
        }

        rtps_util_add_entity_id(sil_tree_writer,
          tvb,
          offset,
          hf_rtps_sm_wrentity_id,
          hf_rtps_sm_wrentity_id_key,
          hf_rtps_sm_wrentity_id_kind,
          ett_rtps_wrentity,
          "writerEntityId",
          NULL);

        if (num_writers == 1) {
          offset = old_offset;
        } else {
          offset += 4;
        }

        if (!(flags & FLAG_VIRTUAL_HEARTBEAT_N)) {
          proto_tree_add_item(sil_tree_writer, hf_rtps_virtual_heartbeat_num_virtual_guids, tvb,
            offset, 4, encoding);
          num_virtual_guids = tvb_get_guint32(tvb, offset, encoding);
          offset += 4;
        } else {
          num_virtual_guids = 0;
        }

        /** Virtual GUID list **/
        if (num_virtual_guids != 0) {
          proto_tree *sil_tree_virtual_guid_list;
          guint32 current_virtual_guid_index;

          sil_tree_virtual_guid_list = proto_tree_add_subtree_format(sil_tree_writer, tvb, offset, -1,
           ett_rtps_virtual_guid_heartbeat_virtual_list, NULL, "Virtual GUID List");

          current_virtual_guid_index = 0;

          while (current_virtual_guid_index < num_virtual_guids) {
            proto_tree *sil_tree_virtual_guid;
            sil_tree_virtual_guid = proto_tree_add_subtree_format(sil_tree_virtual_guid_list, tvb, offset, -1,
                ett_rtps_virtual_guid_heartbeat_virtual, NULL, "virtualGUID[%d]", current_virtual_guid_index);

            if (!(flags & FLAG_VIRTUAL_HEARTBEAT_V)) {
              old_offset = offset;
              offset = virtual_guid_offset;
            }

            /*rtps_util_add_generic_guid_v2(sil_tree_virtual_guid,
            tvb,
            offset,
            "virtualGUID",
            buffer,
            MAX_GUID_SIZE);*/

            if (!(flags & FLAG_VIRTUAL_HEARTBEAT_V)) {
              offset = old_offset;
            } else {
              offset += 16;
            }

            /* firstVirtualSN */
            rtps_util_add_seq_number(sil_tree_virtual_guid,
              tvb,
              offset,
              encoding,
              "firstVirtualSN");
            offset += 8;

            /* lastVirtualSN */
            rtps_util_add_seq_number(sil_tree_virtual_guid,
              tvb,
              offset,
              encoding,
              "lastVirtualSN");
            offset += 8;

            /* firstRTPSSN */
            rtps_util_add_seq_number(sil_tree_virtual_guid,
              tvb,
              offset,
              encoding,
              "firstRTPSSN");
            offset += 8;

            /* lastRTPSSN */
            rtps_util_add_seq_number(sil_tree_virtual_guid,
              tvb,
              offset,
              encoding,
              "lastRTPSSN");
            offset += 8;

            current_virtual_guid_index++;
          }
        }

        current_writer_index++;
      }
    }

    /* Count */
    proto_tree_add_item(tree, hf_rtps_virtual_heartbeat_count, tvb, offset, 4, encoding);
  }
static void dissect_HEARTBEAT_VIRTUAL(tvbuff_t *tvb, packet_info *pinfo _U_, gint offset,
                guint8 flags, const guint encoding, int octets_to_next_header, proto_tree *tree,
                guint16 vendor_id _U_, endpoint_guid *guid) {

     

    guint32 num_writers, num_virtual_guids, wid;
    gint writer_id_offset, virtual_guid_offset = 0, old_offset;
    proto_item *octet_item, *ti;

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

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

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

     
    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);
    writer_id_offset = offset;
    offset += 4;
    guid->entity_id = wid;
    guid->fields_present |= GUID_HAS_ENTITY_ID;
    rtps_util_topic_info_add_tree(tree, tvb, offset, guid);

     
    if (!(flags & FLAG_VIRTUAL_HEARTBEAT_V) && !(flags & FLAG_VIRTUAL_HEARTBEAT_N)) {
       
      virtual_guid_offset = offset;
      offset += 16;
    }

     
    ti = proto_tree_add_item(tree, hf_rtps_virtual_heartbeat_num_writers, tvb,
        offset, 4, encoding);
    if (flags & FLAG_VIRTUAL_HEARTBEAT_W) {
      num_writers = tvb_get_guint32(tvb, offset, encoding);
      offset += 4;
    } else {
      proto_item_set_text(ti, "numWriters: 1");
      num_writers = 1;
    }

    {
       
      proto_tree *sil_tree_writer_list;
      guint32 current_writer_index;

       
      sil_tree_writer_list = proto_tree_add_subtree_format(tree, tvb, offset, -1,
           ett_rtps_writer_heartbeat_virtual_list, NULL, "Writer List");

      current_writer_index = 0;

      while (current_writer_index < num_writers) {
        proto_tree *sil_tree_writer;
        sil_tree_writer = proto_tree_add_subtree_format(sil_tree_writer_list, tvb, offset, -1,
           ett_rtps_writer_heartbeat_virtual, NULL, "writer[%d]", current_writer_index);

        if (num_writers == 1) {
          old_offset = offset;
          offset = writer_id_offset;
        }

        rtps_util_add_entity_id(sil_tree_writer,
          tvb,
          offset,
          hf_rtps_sm_wrentity_id,
          hf_rtps_sm_wrentity_id_key,
          hf_rtps_sm_wrentity_id_kind,
          ett_rtps_wrentity,
          "writerEntityId",
          NULL);

        if (num_writers == 1) {
          offset = old_offset;
        } else {
          offset += 4;
        }

        if (!(flags & FLAG_VIRTUAL_HEARTBEAT_N)) {
          proto_tree_add_item(sil_tree_writer, hf_rtps_virtual_heartbeat_num_virtual_guids, tvb,
            offset, 4, encoding);
          num_virtual_guids = tvb_get_guint32(tvb, offset, encoding);
          offset += 4;
        } else {
          num_virtual_guids = 0;
        }

         
        if (num_virtual_guids != 0) {
          proto_tree *sil_tree_virtual_guid_list;
          guint32 current_virtual_guid_index;

          sil_tree_virtual_guid_list = proto_tree_add_subtree_format(sil_tree_writer, tvb, offset, -1,
           ett_rtps_virtual_guid_heartbeat_virtual_list, NULL, "Virtual GUID List");

          current_virtual_guid_index = 0;

          while (current_virtual_guid_index < num_virtual_guids) {
            proto_tree *sil_tree_virtual_guid;
            sil_tree_virtual_guid = proto_tree_add_subtree_format(sil_tree_virtual_guid_list, tvb, offset, -1,
                ett_rtps_virtual_guid_heartbeat_virtual, NULL, "virtualGUID[%d]", current_virtual_guid_index);

            if (!(flags & FLAG_VIRTUAL_HEARTBEAT_V)) {
              old_offset = offset;
              offset = virtual_guid_offset;
            }

             

            if (!(flags & FLAG_VIRTUAL_HEARTBEAT_V)) {
              offset = old_offset;
            } else {
              offset += 16;
            }

             
            rtps_util_add_seq_number(sil_tree_virtual_guid,
              tvb,
              offset,
              encoding,
              "firstVirtualSN");
            offset += 8;

             
            rtps_util_add_seq_number(sil_tree_virtual_guid,
              tvb,
              offset,
              encoding,
              "lastVirtualSN");
            offset += 8;

             
            rtps_util_add_seq_number(sil_tree_virtual_guid,
              tvb,
              offset,
              encoding,
              "firstRTPSSN");
            offset += 8;

             
            rtps_util_add_seq_number(sil_tree_virtual_guid,
              tvb,
              offset,
              encoding,
              "lastRTPSSN");
            offset += 8;

            current_virtual_guid_index++;
          }
        }

        current_writer_index++;
      }
    }

     
    proto_tree_add_item(tree, hf_rtps_virtual_heartbeat_count, tvb, offset, 4, encoding);
  }