aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--epan/dissectors/packet-lbtru.c1
-rw-r--r--ui/qt/CMakeLists.txt12
-rw-r--r--ui/qt/Makefile.am8
-rw-r--r--ui/qt/Makefile.common16
-rw-r--r--ui/qt/QtShark.pro12
-rw-r--r--ui/qt/lbm_lbtrm_transport_dialog.cpp1655
-rw-r--r--ui/qt/lbm_lbtrm_transport_dialog.h132
-rw-r--r--ui/qt/lbm_lbtrm_transport_dialog.ui836
-rw-r--r--ui/qt/lbm_lbtru_transport_dialog.cpp2251
-rw-r--r--ui/qt/lbm_lbtru_transport_dialog.h156
-rw-r--r--ui/qt/lbm_lbtru_transport_dialog.ui1301
-rw-r--r--ui/qt/lbm_stream_dialog.cpp455
-rw-r--r--ui/qt/lbm_stream_dialog.h85
-rw-r--r--ui/qt/lbm_stream_dialog.ui159
-rw-r--r--ui/qt/lbm_uimflow_dialog.cpp668
-rw-r--r--ui/qt/lbm_uimflow_dialog.h117
-rw-r--r--ui/qt/lbm_uimflow_dialog.ui326
-rw-r--r--ui/qt/main_window.h15
-rw-r--r--ui/qt/main_window.ui119
-rw-r--r--ui/qt/main_window_slots.cpp100
20 files changed, 8423 insertions, 1 deletions
diff --git a/epan/dissectors/packet-lbtru.c b/epan/dissectors/packet-lbtru.c
index 64a87d8d7e..b557f088d0 100644
--- a/epan/dissectors/packet-lbtru.c
+++ b/epan/dissectors/packet-lbtru.c
@@ -2025,6 +2025,7 @@ void proto_reg_handoff_lbtru(void)
lbtru_dissector_handle = new_create_dissector_handle(dissect_lbtru, proto_lbtru);
dissector_add_handle("udp.port", lbtru_dissector_handle); /* for "decode as" */
heur_dissector_add("udp", test_lbtru_packet, proto_lbtru);
+ lbtru_tap_handle = register_tap("lbtru");
}
/* Make sure the low source port is <= the high source port. If not, don't change them. */
diff --git a/ui/qt/CMakeLists.txt b/ui/qt/CMakeLists.txt
index b8b50ba6e3..8f3702f7cd 100644
--- a/ui/qt/CMakeLists.txt
+++ b/ui/qt/CMakeLists.txt
@@ -54,6 +54,10 @@ set(WIRESHARK_QT_HEADERS
io_graph_dialog.h
label_stack.h
layout_preferences_frame.h
+ lbm_lbtrm_transport_dialog.h
+ lbm_lbtru_transport_dialog.h
+ lbm_stream_dialog.h
+ lbm_uimflow_dialog.h
main_status_bar.h
main_welcome.h
main_window.h
@@ -130,6 +134,10 @@ set(WIRESHARK_QT_SRC
io_graph_dialog.cpp
label_stack.cpp
layout_preferences_frame.cpp
+ lbm_lbtrm_transport_dialog.cpp
+ lbm_lbtru_transport_dialog.cpp
+ lbm_stream_dialog.cpp
+ lbm_uimflow_dialog.cpp
main.cpp
main_status_bar.cpp
main_welcome.cpp
@@ -199,6 +207,10 @@ set(WIRESHARK_QT_UI
import_text_dialog.ui
io_graph_dialog.ui
layout_preferences_frame.ui
+ lbm_lbtrm_transport_dialog.ui
+ lbm_lbtru_transport_dialog.ui
+ lbm_stream_dialog.ui
+ lbm_uimflow_dialog.ui
main_welcome.ui
main_window.ui
main_window_preferences_frame.ui
diff --git a/ui/qt/Makefile.am b/ui/qt/Makefile.am
index 1196fcc1d8..71175e8b92 100644
--- a/ui/qt/Makefile.am
+++ b/ui/qt/Makefile.am
@@ -153,6 +153,14 @@ io_graph_dialog.cpp io_graph_dialog.h: ui_io_graph_dialog.h
layout_preferences_frame.cpp layout_preferences_frame.h: ui_layout_preferences_frame.h
+lbm_lbtrm_transport_dialog.cpp lbm_lbtrm_transport_dialog.h: ui_lbm_lbtrm_transport_dialog.h
+
+lbm_lbtru_transport_dialog.cpp lbm_lbtru_transport_dialog.h: ui_lbm_lbtru_transport_dialog.h
+
+lbm_stream_dialog.cpp lbm_stream_dialog.h: ui_lbm_stream_dialog.h
+
+lbm_uimflow_dialog.cpp lbm_uimflow_dialog.h: ui_lbm_uimflow_dialog.h
+
main_welcome.cpp main_welcome.h: ui_main_welcome.h
main_window.cpp main_window_slots.cpp main_window.h: ui_main_window.h
diff --git a/ui/qt/Makefile.common b/ui/qt/Makefile.common
index eeac2f572f..7dac9f025d 100644
--- a/ui/qt/Makefile.common
+++ b/ui/qt/Makefile.common
@@ -43,6 +43,10 @@ NODIST_GENERATED_HEADER_FILES = \
ui_import_text_dialog.h \
ui_io_graph_dialog.h \
ui_layout_preferences_frame.h \
+ ui_lbm_lbtrm_transport_dialog.h \
+ ui_lbm_lbtru_transport_dialog.h \
+ ui_lbm_stream_dialog.h \
+ ui_lbm_uimflow_dialog.h \
ui_main_welcome.h \
ui_main_window.h \
ui_main_window_preferences_frame.h \
@@ -134,6 +138,10 @@ MOC_HDRS = \
io_graph_dialog.h \
label_stack.h \
layout_preferences_frame.h \
+ lbm_lbtrm_transport_dialog.h \
+ lbm_lbtru_transport_dialog.h \
+ lbm_stream_dialog.h \
+ lbm_uimflow_dialog.h \
main_status_bar.h \
main_welcome.h \
main_window.h \
@@ -191,6 +199,10 @@ UI_FILES = \
import_text_dialog.ui \
io_graph_dialog.ui \
layout_preferences_frame.ui \
+ lbm_lbtrm_transport_dialog.ui \
+ lbm_lbtru_transport_dialog.ui \
+ lbm_stream_dialog.ui \
+ lbm_uimflow_dialog.ui \
main_welcome.ui \
main_window.ui \
main_window_preferences_frame.ui \
@@ -298,6 +310,10 @@ WIRESHARK_QT_SRC = \
io_graph_dialog.cpp \
label_stack.cpp \
layout_preferences_frame.cpp \
+ lbm_lbtrm_transport_dialog.cpp \
+ lbm_lbtru_transport_dialog.cpp \
+ lbm_stream_dialog.cpp \
+ lbm_uimflow_dialog.cpp \
main.cpp \
main_status_bar.cpp \
main_welcome.cpp \
diff --git a/ui/qt/QtShark.pro b/ui/qt/QtShark.pro
index 672b634170..13f5f82502 100644
--- a/ui/qt/QtShark.pro
+++ b/ui/qt/QtShark.pro
@@ -233,6 +233,10 @@ FORMS += \
import_text_dialog.ui \
io_graph_dialog.ui \
layout_preferences_frame.ui \
+ lbm_lbtrm_transport_dialog.ui \
+ lbm_lbtru_transport_dialog.ui \
+ lbm_stream_dialog.ui \
+ lbm_uimflow_dialog.ui \
main_welcome.ui \
main_window.ui \
main_window_preferences_frame.ui \
@@ -274,6 +278,10 @@ HEADERS += $$HEADERS_WS_C \
follow_stream_text.h \
font_color_preferences_frame.h \
layout_preferences_frame.h \
+ lbm_lbtrm_transport_dialog.h \
+ lbm_lbtru_transport_dialog.h \
+ lbm_stream_dialog.h \
+ lbm_uimflow_dialog.h \
main_window_preferences_frame.h \
module_preferences_scroll_area.h \
packet_comment_dialog.h \
@@ -588,6 +596,10 @@ SOURCES += \
io_graph_dialog.cpp \
label_stack.cpp \
layout_preferences_frame.cpp \
+ lbm_lbtrm_transport_dialog.cpp \
+ lbm_lbtru_transport_dialog.cpp \
+ lbm_stream_dialog.cpp \
+ lbm_uimflow_dialog.cpp \
main.cpp \
main_status_bar.cpp \
main_welcome.cpp \
diff --git a/ui/qt/lbm_lbtrm_transport_dialog.cpp b/ui/qt/lbm_lbtrm_transport_dialog.cpp
new file mode 100644
index 0000000000..775f7f3c64
--- /dev/null
+++ b/ui/qt/lbm_lbtrm_transport_dialog.cpp
@@ -0,0 +1,1655 @@
+/* lbm_lbtrm_transport_dialog.cpp
+ *
+ * Copyright (c) 2005-2014 Informatica Corporation. All Rights Reserved.
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "lbm_lbtrm_transport_dialog.h"
+#include "ui_lbm_lbtrm_transport_dialog.h"
+
+#include "file.h"
+
+#include "wireshark_application.h"
+
+#include <QClipboard>
+#include <QMessageBox>
+#include <QTreeWidget>
+#include <QTreeWidgetItemIterator>
+#include <QMenu>
+#include <epan/packet_info.h>
+#include <epan/tap.h>
+#include <epan/to_str.h>
+#include <epan/wmem/wmem.h>
+#include <epan/dissectors/packet-lbm.h>
+#include <wsutil/nstime.h>
+
+#include <QDebug>
+
+namespace
+{
+ static const int Source_AddressTransport_Column = 0;
+ static const int Source_DataFrames_Column = 1;
+ static const int Source_DataBytes_Column = 2;
+ static const int Source_DataFramesBytes_Column = 3;
+ static const int Source_DataRate_Column = 4;
+ static const int Source_RXDataFrames_Column = 5;
+ static const int Source_RXDataBytes_Column = 6;
+ static const int Source_RXDataFramesBytes_Column = 7;
+ static const int Source_RXDataRate_Column = 8;
+ static const int Source_NCFFrames_Column = 9;
+ static const int Source_NCFCount_Column = 10;
+ static const int Source_NCFBytes_Column = 11;
+ static const int Source_NCFFramesBytes_Column = 12;
+ static const int Source_NCFCountBytes_Column = 13;
+ static const int Source_NCFFramesCount_Column = 14;
+ static const int Source_NCFFramesCountBytes_Column = 15;
+ static const int Source_NCFRate_Column = 16;
+ static const int Source_SMFrames_Column = 17;
+ static const int Source_SMBytes_Column = 18;
+ static const int Source_SMFramesBytes_Column = 19;
+ static const int Source_SMRate_Column = 20;
+
+ static const int Receiver_AddressTransport_Column = 0;
+ static const int Receiver_NAKFrames_Column = 1;
+ static const int Receiver_NAKCount_Column = 2;
+ static const int Receiver_NAKBytes_Column = 3;
+ static const int Receiver_NAKRate_Column = 4;
+
+ static const int Detail_SQN_Column = 0;
+ static const int Detail_Count_Column = 1;
+ static const int Detail_Frame_Column = 2;
+
+ static const double OneKilobit = 1000.0;
+ static const double OneMegabit = OneKilobit * OneKilobit;
+ static const double OneGigabit = OneMegabit * OneKilobit;
+}
+
+static QString format_rate(const nstime_t & elapsed, guint64 bytes)
+{
+ QString result;
+ double elapsed_sec;
+ double rate;
+
+ if (((elapsed.secs == 0) && (elapsed.nsecs == 0)) || (bytes == 0))
+ {
+ return (QString("0"));
+ }
+
+ elapsed_sec = elapsed.secs + (((double)elapsed.nsecs) / 1000000000.0);
+ rate = ((double)(bytes * 8)) / elapsed_sec;
+
+ // Currently rate is in bps
+ if (rate >= OneGigabit)
+ {
+ rate /= OneGigabit;
+ result = QString("%1G").arg(rate, 0, 'f', 2);
+ }
+ else if (rate >= OneMegabit)
+ {
+ rate /= OneMegabit;
+ result = QString("%1M").arg(rate, 0, 'f', 2);
+ }
+ else if (rate >= OneKilobit)
+ {
+ rate /= OneKilobit;
+ result = QString("%1K").arg(rate, 0, 'f', 2);
+ }
+ else
+ {
+ result = QString("%1").arg(rate, 0, 'f', 2);
+ }
+ return (result);
+}
+
+// Note:
+// LBMLBTRMFrameEntry, LBMLBTRMSQNEntry, LBMLBTRMNCFReasonEntry, LBMLBTRMNCFSQNEntry, LBMLBTRMSourceTransportEntry, LBMLBTRMSourceEntry,
+// LBMLBTRMReceiverTransportEntry, and LBMLBTRMReceiverEntry are all derived from a QTreeWidgetItem. Each instantiation can exist
+// in two places: in a QTreeWidget, and in a containing QMap.
+//
+// For example:
+// - LBMLBTRMTransportDialogInfo contains a QMap of the sources (LBMLBTRMSourceEntry) and receivers (LBMLBTRMReceiverEntry)
+// - A source (LBMLBTRMSourceEntry) contains a QMap of the source transports originating from it (LBMLBTRMSourceTransportEntry)
+// - A source transport (LBMLBTRMSourceTransportEntry) contains QMaps of data, RX data, and SM SQNs (LBMLBTRMSQNEntry) and NCF SQNs
+// (LBMLBTRMNCFSQNEntry)
+// - A data SQN (LBMLBTRMSQNEntry) contains a QMap of the frames (LBMLBTRMFrameEntry) in which that SQN appears
+//
+// Not all of the entries actually appear in a QTreeWidget at one time. For example, in the source details, if no specific source
+// transport is selected, nothing is in the source details tree. If Data SQNs is selected, then those details appear in the source
+// details tree. Switching to RX Data SQNs removes whatever is currently in the source details tree, and adds the RX details for
+// the selected transport.
+//
+// The actual owner of one of the above QTreeWidgetItem-derived items is the QMap container in its parent. The item is "loaned" to
+// the QTreeWidget for display.
+//
+// All of this is to explain why
+// 1) we are frequently adding things to a QTreeWidget
+// 2) things are removed (takeTopLevelItem) from a QTreeWidget
+// 3) destruction involves removing all items from all QTreeWidgets (rather than letting QTreeWidget delete them)
+// 4) the destructor for each item has the form
+// <for each QMap container>
+// for (XXXMapIterator it = m_xxx.begin(); it != m_xxx.end(); it++)
+// {
+// delete *it;
+// }
+// m_xxx.clear();
+// The for-loop calls the destructor for each item, while the clear() cleans up the space used by the QMap itself.
+
+// A frame entry
+class LBMLBTRMFrameEntry : public QTreeWidgetItem
+{
+ public:
+ LBMLBTRMFrameEntry(guint32 frame);
+ virtual ~LBMLBTRMFrameEntry(void) { }
+ guint32 getFrame(void) { return (m_frame); }
+
+ private:
+ LBMLBTRMFrameEntry(void) { }
+ guint32 m_frame;
+};
+
+LBMLBTRMFrameEntry::LBMLBTRMFrameEntry(guint32 frame) :
+ QTreeWidgetItem(),
+ m_frame(frame)
+{
+ setText(Detail_SQN_Column, QString(" "));
+ setText(Detail_Count_Column, QString(" "));
+ setText(Detail_Frame_Column, QString("%1").arg(m_frame));
+}
+
+typedef QMap<guint32, LBMLBTRMFrameEntry *> LBMLBTRMFrameMap;
+typedef QMap<guint32, LBMLBTRMFrameEntry *>::iterator LBMLBTRMFrameMapIterator;
+
+// A SQN (SeQuence Number) entry
+class LBMLBTRMSQNEntry : public QTreeWidgetItem
+{
+ public:
+ LBMLBTRMSQNEntry(guint32 sqn);
+ virtual ~LBMLBTRMSQNEntry(void);
+ void processFrame(guint32 frame);
+
+ private:
+ LBMLBTRMSQNEntry(void);
+ guint32 m_sqn;
+ guint32 m_count;
+ LBMLBTRMFrameMap m_frames;
+};
+
+LBMLBTRMSQNEntry::LBMLBTRMSQNEntry(guint32 sqn) :
+ QTreeWidgetItem(),
+ m_sqn(sqn),
+ m_count(0),
+ m_frames()
+{
+ setText(Detail_SQN_Column, QString("%1").arg(m_sqn));
+ setTextAlignment(Detail_SQN_Column, Qt::AlignRight);
+ setText(Detail_Count_Column, QString("%1").arg(m_count));
+ setTextAlignment(Detail_Count_Column, Qt::AlignRight);
+ setText(Detail_Frame_Column, QString(" "));
+}
+
+LBMLBTRMSQNEntry::~LBMLBTRMSQNEntry(void)
+{
+ for (LBMLBTRMFrameMapIterator it = m_frames.begin(); it != m_frames.end(); it++)
+ {
+ delete *it;
+ }
+ m_frames.clear();
+}
+
+void LBMLBTRMSQNEntry::processFrame(guint32 frame)
+{
+ LBMLBTRMFrameMapIterator it;
+
+ it = m_frames.find(frame);
+ if (m_frames.end() == it)
+ {
+ LBMLBTRMFrameEntry * entry = new LBMLBTRMFrameEntry(frame);
+ m_frames.insert(frame, entry);
+ addChild(entry);
+ sortChildren(Detail_Frame_Column, Qt::AscendingOrder);
+ }
+ m_count++;
+ setText(Detail_Count_Column, QString("%1").arg(m_count));
+ setTextAlignment(Detail_Count_Column, Qt::AlignRight);
+}
+
+// An NCF (Nak ConFirmation) Reason entry
+class LBMLBTRMNCFReasonEntry : public QTreeWidgetItem
+{
+ public:
+ LBMLBTRMNCFReasonEntry(guint8 reason);
+ virtual ~LBMLBTRMNCFReasonEntry(void);
+ void processFrame(guint32 frame);
+
+ private:
+ LBMLBTRMNCFReasonEntry(void);
+ guint8 m_reason;
+ QString m_reason_string;
+ guint32 m_count;
+ LBMLBTRMFrameMap m_frames;
+};
+
+LBMLBTRMNCFReasonEntry::LBMLBTRMNCFReasonEntry(guint8 reason) :
+ QTreeWidgetItem(),
+ m_reason(reason),
+ m_reason_string(),
+ m_count(0),
+ m_frames()
+{
+ switch (m_reason)
+ {
+ case LBTRM_NCF_REASON_NO_RETRY:
+ m_reason_string = "No Retry";
+ break;
+ case LBTRM_NCF_REASON_IGNORED:
+ m_reason_string = "Ignored";
+ break;
+ case LBTRM_NCF_REASON_RX_DELAY:
+ m_reason_string = "Retransmit Delay";
+ break;
+ case LBTRM_NCF_REASON_SHED:
+ m_reason_string = "Shed";
+ break;
+ default:
+ m_reason_string = QString("Unknown (%1)").arg(m_reason);
+ break;
+ }
+ setText(Detail_SQN_Column, m_reason_string);
+ setText(Detail_Count_Column, QString("%1").arg(m_count));
+ setTextAlignment(Detail_Count_Column, Qt::AlignRight);
+ setText(Detail_Frame_Column, QString(" "));
+}
+
+LBMLBTRMNCFReasonEntry::~LBMLBTRMNCFReasonEntry(void)
+{
+ for (LBMLBTRMFrameMapIterator it = m_frames.begin(); it != m_frames.end(); it++)
+ {
+ delete *it;
+ }
+ m_frames.clear();
+}
+
+void LBMLBTRMNCFReasonEntry::processFrame(guint32 frame)
+{
+ LBMLBTRMFrameMapIterator it;
+
+ it = m_frames.find(frame);
+ if (m_frames.end() == it)
+ {
+ LBMLBTRMFrameEntry * entry = new LBMLBTRMFrameEntry(frame);
+ m_frames.insert(frame, entry);
+ addChild(entry);
+ sortChildren(Detail_Frame_Column, Qt::AscendingOrder);
+ }
+ m_count++;
+ setText(Detail_Count_Column, QString("%1").arg(m_count));
+ setTextAlignment(Detail_Count_Column, Qt::AlignRight);
+}
+
+typedef QMap<guint32, LBMLBTRMNCFReasonEntry *> LBMLBTRMNCFReasonMap;
+typedef QMap<guint32, LBMLBTRMNCFReasonEntry *>::iterator LBMLBTRMNCFReasonMapIterator;
+
+// An NCF SQN entry
+class LBMLBTRMNCFSQNEntry : public QTreeWidgetItem
+{
+ public:
+ LBMLBTRMNCFSQNEntry(guint32 sqn);
+ virtual ~LBMLBTRMNCFSQNEntry(void);
+ void processFrame(guint8 reason, guint32 frame);
+
+ private:
+ LBMLBTRMNCFSQNEntry(void);
+ guint32 m_sqn;
+ guint32 m_count;
+ LBMLBTRMNCFReasonMap m_reasons;
+};
+
+LBMLBTRMNCFSQNEntry::LBMLBTRMNCFSQNEntry(guint32 sqn) :
+ QTreeWidgetItem(),
+ m_sqn(sqn),
+ m_count(0),
+ m_reasons()
+{
+ setText(Detail_SQN_Column, QString("%1").arg(m_sqn));
+ setTextAlignment(Detail_SQN_Column, Qt::AlignRight);
+ setText(Detail_Count_Column, QString("%1").arg(m_count));
+ setTextAlignment(Detail_Count_Column, Qt::AlignRight);
+ setText(Detail_Frame_Column, QString(" "));
+}
+
+LBMLBTRMNCFSQNEntry::~LBMLBTRMNCFSQNEntry(void)
+{
+ for (LBMLBTRMNCFReasonMapIterator it = m_reasons.begin(); it != m_reasons.end(); it++)
+ {
+ delete *it;
+ }
+ m_reasons.clear();
+}
+
+void LBMLBTRMNCFSQNEntry::processFrame(guint8 reason, guint32 frame)
+{
+ LBMLBTRMNCFReasonMapIterator it;
+ LBMLBTRMNCFReasonEntry * entry = NULL;
+
+ it = m_reasons.find(reason);
+ if (m_reasons.end() == it)
+ {
+ entry = new LBMLBTRMNCFReasonEntry(reason);
+ m_reasons.insert(reason, entry);
+ addChild(entry);
+ sortChildren(Detail_Frame_Column, Qt::AscendingOrder);
+ }
+ else
+ {
+ entry = it.value();
+ }
+ m_count++;
+ setText(Detail_Count_Column, QString("%1").arg(m_count));
+ setTextAlignment(Detail_Count_Column, Qt::AlignRight);
+ entry->processFrame(frame);
+}
+
+typedef QMap<guint32, LBMLBTRMSQNEntry *> LBMLBTRMSQNMap;
+typedef QMap<guint32, LBMLBTRMSQNEntry *>::iterator LBMLBTRMSQNMapIterator;
+typedef QMap<guint32, LBMLBTRMNCFSQNEntry *> LBMLBTRMNCFSQNMap;
+typedef QMap<guint32, LBMLBTRMNCFSQNEntry *>::iterator LBMLBTRMNCFSQNMapIterator;
+
+// A source transport entry
+class LBMLBTRMSourceTransportEntry : public QTreeWidgetItem
+{
+ friend class LBMLBTRMTransportDialog;
+
+ public:
+ LBMLBTRMSourceTransportEntry(const QString & transport);
+ virtual ~LBMLBTRMSourceTransportEntry(void);
+ void processPacket(const packet_info * pinfo, const lbm_lbtrm_tap_info_t * tap_info);
+
+ protected:
+ QString m_transport;
+
+ private:
+ LBMLBTRMSourceTransportEntry(void) { }
+ void fillItem(void);
+ guint64 m_data_frames;
+ guint64 m_data_bytes;
+ guint64 m_rx_data_frames;
+ guint64 m_rx_data_bytes;
+ guint64 m_ncf_frames;
+ guint64 m_ncf_count;
+ guint64 m_ncf_bytes;
+ guint64 m_sm_frames;
+ guint64 m_sm_bytes;
+ nstime_t m_first_frame_timestamp;
+ bool m_first_frame_timestamp_valid;
+ nstime_t m_last_frame_timestamp;
+
+ protected:
+ LBMLBTRMSQNMap m_data_sqns;
+ LBMLBTRMSQNMap m_rx_data_sqns;
+ LBMLBTRMNCFSQNMap m_ncf_sqns;
+ LBMLBTRMSQNMap m_sm_sqns;
+};
+
+LBMLBTRMSourceTransportEntry::LBMLBTRMSourceTransportEntry(const QString & transport) :
+ QTreeWidgetItem(),
+ m_transport(transport),
+ m_data_frames(0),
+ m_data_bytes(0),
+ m_rx_data_frames(0),
+ m_rx_data_bytes(0),
+ m_ncf_frames(0),
+ m_ncf_count(0),
+ m_ncf_bytes(0),
+ m_sm_frames(0),
+ m_sm_bytes(0),
+ m_first_frame_timestamp_valid(false),
+ m_data_sqns(),
+ m_rx_data_sqns(),
+ m_ncf_sqns(),
+ m_sm_sqns()
+{
+ m_first_frame_timestamp.secs = 0;
+ m_first_frame_timestamp.nsecs = 0;
+ m_last_frame_timestamp.secs = 0;
+ m_last_frame_timestamp.nsecs = 0;
+ setText(Source_AddressTransport_Column, m_transport);
+}
+
+LBMLBTRMSourceTransportEntry::~LBMLBTRMSourceTransportEntry(void)
+{
+ for (LBMLBTRMSQNMapIterator it = m_data_sqns.begin(); it != m_data_sqns.end(); it++)
+ {
+ delete *it;
+ }
+ m_data_sqns.clear();
+
+ for (LBMLBTRMSQNMapIterator it = m_rx_data_sqns.begin(); it != m_rx_data_sqns.end(); it++)
+ {
+ delete *it;
+ }
+ m_rx_data_sqns.clear();
+
+ for (LBMLBTRMNCFSQNMapIterator it = m_ncf_sqns.begin(); it != m_ncf_sqns.end(); it++)
+ {
+ delete *it;
+ }
+ m_ncf_sqns.clear();
+
+ for (LBMLBTRMSQNMapIterator it = m_sm_sqns.begin(); it != m_sm_sqns.end(); it++)
+ {
+ delete *it;
+ }
+ m_sm_sqns.clear();
+}
+
+void LBMLBTRMSourceTransportEntry::processPacket(const packet_info * pinfo, const lbm_lbtrm_tap_info_t * tap_info)
+{
+ if (m_first_frame_timestamp_valid)
+ {
+ if (nstime_cmp(&(pinfo->fd->abs_ts), &m_first_frame_timestamp) < 0)
+ {
+ nstime_copy(&(m_first_frame_timestamp), &(pinfo->fd->abs_ts));
+ }
+ }
+ else
+ {
+ nstime_copy(&(m_first_frame_timestamp), &(pinfo->fd->abs_ts));
+ m_first_frame_timestamp_valid = true;
+ }
+ if (nstime_cmp(&(pinfo->fd->abs_ts), &m_last_frame_timestamp) > 0)
+ {
+ nstime_copy(&(m_last_frame_timestamp), &(pinfo->fd->abs_ts));
+ }
+ if (tap_info->type == LBTRM_PACKET_TYPE_DATA)
+ {
+ LBMLBTRMSQNEntry * sqn = NULL;
+ LBMLBTRMSQNMapIterator it;
+
+ if (tap_info->retransmission)
+ {
+ m_rx_data_frames++;
+ m_rx_data_bytes += pinfo->fd->pkt_len;
+ it = m_rx_data_sqns.find(tap_info->sqn);
+ if (m_rx_data_sqns.end() == it)
+ {
+ sqn = new LBMLBTRMSQNEntry(tap_info->sqn);
+ m_rx_data_sqns.insert(tap_info->sqn, sqn);
+ }
+ else
+ {
+ sqn = it.value();
+ }
+ }
+ else
+ {
+ m_data_frames++;
+ m_data_bytes += pinfo->fd->pkt_len;
+ it = m_data_sqns.find(tap_info->sqn);
+ if (m_data_sqns.end() == it)
+ {
+ sqn = new LBMLBTRMSQNEntry(tap_info->sqn);
+ m_data_sqns.insert(tap_info->sqn, sqn);
+ }
+ else
+ {
+ sqn = it.value();
+ }
+ }
+ sqn->processFrame(pinfo->fd->num);
+ }
+ else if (tap_info->type == LBTRM_PACKET_TYPE_NCF)
+ {
+ guint16 idx;
+ LBMLBTRMNCFSQNMapIterator it;
+ LBMLBTRMNCFSQNEntry * sqn = NULL;
+
+ m_ncf_frames++;
+ m_ncf_bytes += pinfo->fd->pkt_len;
+ m_ncf_count += (guint64)tap_info->num_sqns;
+ for (idx = 0; idx < tap_info->num_sqns; idx++)
+ {
+ it = m_ncf_sqns.find(tap_info->sqns[idx]);
+ if (m_ncf_sqns.end() == it)
+ {
+ sqn = new LBMLBTRMNCFSQNEntry(tap_info->sqns[idx]);
+ m_ncf_sqns.insert(tap_info->sqns[idx], sqn);
+ }
+ else
+ {
+ sqn = it.value();
+ }
+ sqn->processFrame(tap_info->ncf_reason, pinfo->fd->num);
+ }
+ }
+ else if (tap_info->type == LBTRM_PACKET_TYPE_SM)
+ {
+ LBMLBTRMSQNEntry * sqn = NULL;
+ LBMLBTRMSQNMapIterator it;
+
+ m_sm_frames++;
+ m_sm_bytes += pinfo->fd->pkt_len;
+ it = m_sm_sqns.find(tap_info->sqn);
+ if (m_sm_sqns.end() == it)
+ {
+ sqn = new LBMLBTRMSQNEntry(tap_info->sqn);
+ m_sm_sqns.insert(tap_info->sqn, sqn);
+ }
+ else
+ {
+ sqn = it.value();
+ }
+ sqn->processFrame(pinfo->fd->num);
+ }
+ else
+ {
+ return;
+ }
+ fillItem();
+}
+
+void LBMLBTRMSourceTransportEntry::fillItem(void)
+{
+ nstime_t delta;
+
+ nstime_delta(&delta, &m_last_frame_timestamp, &m_first_frame_timestamp);
+ setText(Source_DataFrames_Column, QString("%1").arg(m_data_frames));
+ setTextAlignment(Source_DataFrames_Column, Qt::AlignRight);
+ setText(Source_DataBytes_Column, QString("%1").arg(m_data_bytes));
+ setTextAlignment(Source_DataBytes_Column, Qt::AlignRight);
+ setText(Source_DataFramesBytes_Column, QString("%1/%2").arg(m_data_frames).arg(m_data_bytes));
+ setTextAlignment(Source_DataFramesBytes_Column, Qt::AlignHCenter);
+ setText(Source_DataRate_Column, format_rate(delta, m_data_bytes));
+ setTextAlignment(Source_DataRate_Column, Qt::AlignRight);
+ setText(Source_RXDataFrames_Column, QString("%1").arg(m_rx_data_frames));
+ setTextAlignment(Source_RXDataFrames_Column, Qt::AlignRight);
+ setText(Source_RXDataBytes_Column, QString("%1").arg(m_rx_data_bytes));
+ setTextAlignment(Source_RXDataBytes_Column, Qt::AlignRight);
+ setText(Source_RXDataFramesBytes_Column, QString("%1/%2").arg(m_rx_data_frames).arg(m_rx_data_bytes));
+ setTextAlignment(Source_RXDataFramesBytes_Column, Qt::AlignHCenter);
+ setText(Source_RXDataRate_Column, format_rate(delta, m_rx_data_bytes));
+ setTextAlignment(Source_RXDataRate_Column, Qt::AlignRight);
+ setText(Source_NCFFrames_Column, QString("%1").arg(m_ncf_frames));
+ setTextAlignment(Source_NCFFrames_Column, Qt::AlignRight);
+ setText(Source_NCFCount_Column, QString("%1").arg(m_ncf_count));
+ setTextAlignment(Source_NCFCount_Column, Qt::AlignRight);
+ setText(Source_NCFBytes_Column, QString("%1").arg(m_ncf_bytes));
+ setTextAlignment(Source_NCFBytes_Column, Qt::AlignRight);
+ setText(Source_NCFFramesBytes_Column, QString("%1/%2").arg(m_ncf_frames).arg(m_ncf_bytes));
+ setTextAlignment(Source_NCFFramesBytes_Column, Qt::AlignHCenter);
+ setText(Source_NCFCountBytes_Column, QString("%1/%2").arg(m_ncf_count).arg(m_ncf_bytes));
+ setTextAlignment(Source_NCFCountBytes_Column, Qt::AlignHCenter);
+ setText(Source_NCFFramesCount_Column, QString("%1/%2").arg(m_ncf_count).arg(m_ncf_count));
+ setTextAlignment(Source_NCFFramesCount_Column, Qt::AlignHCenter);
+ setText(Source_NCFFramesCountBytes_Column, QString("%1/%2/%3").arg(m_ncf_frames).arg(m_ncf_count).arg(m_ncf_bytes));
+ setTextAlignment(Source_NCFFramesCountBytes_Column, Qt::AlignHCenter);
+ setText(Source_NCFRate_Column, format_rate(delta, m_ncf_bytes));
+ setTextAlignment(Source_NCFRate_Column, Qt::AlignRight);
+ setText(Source_SMFrames_Column, QString("%1").arg(m_sm_frames));
+ setTextAlignment(Source_SMFrames_Column, Qt::AlignRight);
+ setText(Source_SMBytes_Column, QString("%1").arg(m_sm_bytes));
+ setTextAlignment(Source_SMBytes_Column, Qt::AlignRight);
+ setText(Source_SMFramesBytes_Column, QString("%1/%2").arg(m_sm_frames).arg(m_sm_bytes));
+ setTextAlignment(Source_SMFramesBytes_Column, Qt::AlignHCenter);
+ setText(Source_SMRate_Column, format_rate(delta, m_sm_bytes));
+ setTextAlignment(Source_SMRate_Column, Qt::AlignRight);
+}
+
+typedef QMap<QString, LBMLBTRMSourceTransportEntry *> LBMLBTRMSourceTransportMap;
+typedef QMap<QString, LBMLBTRMSourceTransportEntry *>::iterator LBMLBTRMSourceTransportMapIterator;
+
+// A source (address) entry
+class LBMLBTRMSourceEntry : public QTreeWidgetItem
+{
+ public:
+ LBMLBTRMSourceEntry(const QString & source_address);
+ virtual ~LBMLBTRMSourceEntry(void);
+ void processPacket(const packet_info * pinfo, const lbm_lbtrm_tap_info_t * tap_info);
+
+ private:
+ LBMLBTRMSourceEntry(void) { }
+ void fillItem(void);
+ QString m_address;
+ QString m_transport;
+ guint64 m_data_frames;
+ guint64 m_data_bytes;
+ guint64 m_rx_data_frames;
+ guint64 m_rx_data_bytes;
+ guint64 m_ncf_frames;
+ guint64 m_ncf_count;
+ guint64 m_ncf_bytes;
+ guint64 m_sm_frames;
+ guint64 m_sm_bytes;
+ nstime_t m_first_frame_timestamp;
+ bool m_first_frame_timestamp_valid;
+ nstime_t m_last_frame_timestamp;
+ LBMLBTRMSourceTransportMap m_transports;
+};
+
+LBMLBTRMSourceEntry::LBMLBTRMSourceEntry(const QString & source_address) :
+ QTreeWidgetItem(),
+ m_address(source_address),
+ m_data_frames(0),
+ m_data_bytes(0),
+ m_rx_data_frames(0),
+ m_rx_data_bytes(0),
+ m_ncf_frames(0),
+ m_ncf_count(0),
+ m_ncf_bytes(0),
+ m_sm_frames(0),
+ m_sm_bytes(0),
+ m_first_frame_timestamp_valid(false),
+ m_transports()
+{
+ m_first_frame_timestamp.secs = 0;
+ m_first_frame_timestamp.nsecs = 0;
+ m_last_frame_timestamp.secs = 0;
+ m_last_frame_timestamp.nsecs = 0;
+ setText(Source_AddressTransport_Column, m_address);
+}
+
+LBMLBTRMSourceEntry::~LBMLBTRMSourceEntry(void)
+{
+ for (LBMLBTRMSourceTransportMapIterator it = m_transports.begin(); it != m_transports.end(); it++)
+ {
+ delete *it;
+ }
+ m_transports.clear();
+}
+
+void LBMLBTRMSourceEntry::processPacket(const packet_info * pinfo, const lbm_lbtrm_tap_info_t * tap_info)
+{
+ LBMLBTRMSourceTransportEntry * transport = NULL;
+ LBMLBTRMSourceTransportMapIterator it;
+
+ if (m_first_frame_timestamp_valid)
+ {
+ if (nstime_cmp(&(pinfo->fd->abs_ts), &m_first_frame_timestamp) < 0)
+ {
+ nstime_copy(&(m_first_frame_timestamp), &(pinfo->fd->abs_ts));
+ }
+ }
+ else
+ {
+ nstime_copy(&(m_first_frame_timestamp), &(pinfo->fd->abs_ts));
+ m_first_frame_timestamp_valid = true;
+ }
+ if (nstime_cmp(&(pinfo->fd->abs_ts), &m_last_frame_timestamp) > 0)
+ {
+ nstime_copy(&(m_last_frame_timestamp), &(pinfo->fd->abs_ts));
+ }
+ if (tap_info->type == LBTRM_PACKET_TYPE_DATA)
+ {
+ if (tap_info->retransmission)
+ {
+ m_rx_data_frames++;
+ m_rx_data_bytes += pinfo->fd->pkt_len;
+ }
+ else
+ {
+ m_data_frames++;
+ m_data_bytes += pinfo->fd->pkt_len;
+ }
+ }
+ else if (tap_info->type == LBTRM_PACKET_TYPE_NCF)
+ {
+ m_ncf_frames++;
+ m_ncf_bytes += pinfo->fd->pkt_len;
+ m_ncf_count += tap_info->num_sqns;
+ }
+ else if (tap_info->type == LBTRM_PACKET_TYPE_SM)
+ {
+ m_sm_frames++;
+ m_sm_bytes += pinfo->fd->pkt_len;
+ }
+
+ it = m_transports.find(tap_info->transport);
+ if (m_transports.end() == it)
+ {
+ transport = new LBMLBTRMSourceTransportEntry(tap_info->transport);
+ m_transports.insert(tap_info->transport, transport);
+ addChild(transport);
+ sortChildren(Source_AddressTransport_Column, Qt::AscendingOrder);
+ }
+ else
+ {
+ transport = it.value();
+ }
+ fillItem();
+ transport->processPacket(pinfo, tap_info);
+}
+
+void LBMLBTRMSourceEntry::fillItem(void)
+{
+ nstime_t delta;
+
+ nstime_delta(&delta, &m_last_frame_timestamp, &m_first_frame_timestamp);
+ setText(Source_DataFrames_Column, QString("%1").arg(m_data_frames));
+ setTextAlignment(Source_DataFrames_Column, Qt::AlignRight);
+ setText(Source_DataBytes_Column, QString("%1").arg(m_data_bytes));
+ setTextAlignment(Source_DataBytes_Column, Qt::AlignRight);
+ setText(Source_DataFramesBytes_Column, QString("%1/%2").arg(m_data_frames).arg(m_data_bytes));
+ setTextAlignment(Source_DataFramesBytes_Column, Qt::AlignHCenter);
+ setText(Source_DataRate_Column, format_rate(delta, m_data_bytes));
+ setTextAlignment(Source_DataRate_Column, Qt::AlignRight);
+ setText(Source_RXDataFrames_Column, QString("%1").arg(m_rx_data_frames));
+ setTextAlignment(Source_RXDataFrames_Column, Qt::AlignRight);
+ setText(Source_RXDataBytes_Column, QString("%1").arg(m_rx_data_bytes));
+ setTextAlignment(Source_RXDataBytes_Column, Qt::AlignRight);
+ setText(Source_RXDataFramesBytes_Column, QString("%1/%2").arg(m_rx_data_frames).arg(m_rx_data_bytes));
+ setTextAlignment(Source_RXDataFramesBytes_Column, Qt::AlignHCenter);
+ setText(Source_RXDataRate_Column, format_rate(delta, m_rx_data_bytes));
+ setTextAlignment(Source_RXDataRate_Column, Qt::AlignRight);
+ setText(Source_NCFFrames_Column, QString("%1").arg(m_ncf_frames));
+ setTextAlignment(Source_NCFFrames_Column, Qt::AlignRight);
+ setText(Source_NCFCount_Column, QString("%1").arg(m_ncf_count));
+ setTextAlignment(Source_NCFCount_Column, Qt::AlignRight);
+ setText(Source_NCFBytes_Column, QString("%1").arg(m_ncf_bytes));
+ setTextAlignment(Source_NCFBytes_Column, Qt::AlignRight);
+ setText(Source_NCFFramesBytes_Column, QString("%1/%2").arg(m_ncf_frames).arg(m_ncf_bytes));
+ setTextAlignment(Source_NCFFramesBytes_Column, Qt::AlignHCenter);
+ setText(Source_NCFCountBytes_Column, QString("%1/%2").arg(m_ncf_count).arg(m_ncf_bytes));
+ setTextAlignment(Source_NCFCountBytes_Column, Qt::AlignHCenter);
+ setText(Source_NCFFramesCount_Column, QString("%1/%2").arg(m_ncf_frames).arg(m_ncf_count));
+ setTextAlignment(Source_NCFFramesCount_Column, Qt::AlignHCenter);
+ setText(Source_NCFFramesCountBytes_Column, QString("%1/%2/%3").arg(m_ncf_frames).arg(m_ncf_count).arg(m_ncf_bytes));
+ setTextAlignment(Source_NCFFramesCountBytes_Column, Qt::AlignHCenter);
+ setText(Source_NCFRate_Column, format_rate(delta, m_ncf_bytes));
+ setTextAlignment(Source_NCFRate_Column, Qt::AlignRight);
+ setText(Source_SMFrames_Column, QString("%1").arg(m_sm_frames));
+ setTextAlignment(Source_SMFrames_Column, Qt::AlignRight);
+ setText(Source_SMBytes_Column, QString("%1").arg(m_sm_bytes));
+ setTextAlignment(Source_SMBytes_Column, Qt::AlignRight);
+ setText(Source_SMFramesBytes_Column, QString("%1/%2").arg(m_sm_frames).arg(m_sm_bytes));
+ setTextAlignment(Source_SMFramesBytes_Column, Qt::AlignRight);
+ setText(Source_SMRate_Column, format_rate(delta, m_sm_bytes));
+ setTextAlignment(Source_SMRate_Column, Qt::AlignRight);
+}
+
+typedef QMap<QString, LBMLBTRMSourceEntry *> LBMLBTRMSourceMap;
+typedef QMap<QString, LBMLBTRMSourceEntry *>::iterator LBMLBTRMSourceMapIterator;
+
+// A receiver transport entry
+class LBMLBTRMReceiverTransportEntry : public QTreeWidgetItem
+{
+ friend class LBMLBTRMTransportDialog;
+
+ public:
+ LBMLBTRMReceiverTransportEntry(const QString & transport);
+ virtual ~LBMLBTRMReceiverTransportEntry(void);
+ void processPacket(const packet_info * pinfo, const lbm_lbtrm_tap_info_t * tap_info);
+
+ private:
+ LBMLBTRMReceiverTransportEntry(void) { }
+ void fillItem(void);
+ QString m_transport;
+ guint64 m_nak_frames;
+ guint64 m_nak_count;
+ guint64 m_nak_bytes;
+ nstime_t m_first_frame_timestamp;
+ bool m_first_frame_timestamp_valid;
+ nstime_t m_last_frame_timestamp;
+
+ protected:
+ LBMLBTRMSQNMap m_nak_sqns;
+};
+
+LBMLBTRMReceiverTransportEntry::LBMLBTRMReceiverTransportEntry(const QString & transport) :
+ QTreeWidgetItem(),
+ m_transport(transport),
+ m_nak_frames(0),
+ m_nak_count(0),
+ m_nak_bytes(0),
+ m_first_frame_timestamp_valid(false),
+ m_nak_sqns()
+{
+ m_first_frame_timestamp.secs = 0;
+ m_first_frame_timestamp.nsecs = 0;
+ m_last_frame_timestamp.secs = 0;
+ m_last_frame_timestamp.nsecs = 0;
+ setText(Receiver_AddressTransport_Column, m_transport);
+}
+
+LBMLBTRMReceiverTransportEntry::~LBMLBTRMReceiverTransportEntry(void)
+{
+ for (LBMLBTRMSQNMapIterator it = m_nak_sqns.begin(); it != m_nak_sqns.end(); it++)
+ {
+ delete *it;
+ }
+ m_nak_sqns.clear();
+}
+
+void LBMLBTRMReceiverTransportEntry::processPacket(const packet_info * pinfo, const lbm_lbtrm_tap_info_t * tap_info)
+{
+ if (m_first_frame_timestamp_valid)
+ {
+ if (nstime_cmp(&(pinfo->fd->abs_ts), &m_first_frame_timestamp) < 0)
+ {
+ nstime_copy(&(m_first_frame_timestamp), &(pinfo->fd->abs_ts));
+ }
+ }
+ else
+ {
+ nstime_copy(&(m_first_frame_timestamp), &(pinfo->fd->abs_ts));
+ m_first_frame_timestamp_valid = true;
+ }
+ if (nstime_cmp(&(pinfo->fd->abs_ts), &m_last_frame_timestamp) > 0)
+ {
+ nstime_copy(&(m_last_frame_timestamp), &(pinfo->fd->abs_ts));
+ }
+ if (tap_info->type == LBTRM_PACKET_TYPE_NAK)
+ {
+ guint16 idx;
+ LBMLBTRMSQNEntry * sqn = NULL;
+ LBMLBTRMSQNMapIterator it;
+
+ m_nak_frames++;
+ m_nak_bytes += pinfo->fd->pkt_len;
+ m_nak_count += tap_info->num_sqns;
+ for (idx = 0; idx < tap_info->num_sqns; idx++)
+ {
+ it = m_nak_sqns.find(tap_info->sqns[idx]);
+ if (m_nak_sqns.end() == it)
+ {
+ sqn = new LBMLBTRMSQNEntry(tap_info->sqns[idx]);
+ m_nak_sqns.insert(tap_info->sqns[idx], sqn);
+ }
+ else
+ {
+ sqn = it.value();
+ }
+ sqn->processFrame(pinfo->fd->num);
+ }
+ }
+ else
+ {
+ return;
+ }
+ fillItem();
+}
+
+void LBMLBTRMReceiverTransportEntry::fillItem(void)
+{
+ nstime_t delta;
+
+ nstime_delta(&delta, &m_last_frame_timestamp, &m_first_frame_timestamp);
+ setText(Receiver_NAKFrames_Column, QString("%1").arg(m_nak_frames));
+ setTextAlignment(Receiver_NAKFrames_Column, Qt::AlignRight);
+ setText(Receiver_NAKCount_Column, QString("%1").arg(m_nak_count));
+ setTextAlignment(Receiver_NAKCount_Column, Qt::AlignRight);
+ setText(Receiver_NAKBytes_Column, QString("%1").arg(m_nak_bytes));
+ setTextAlignment(Receiver_NAKBytes_Column, Qt::AlignRight);
+ setText(Receiver_NAKRate_Column, format_rate(delta, m_nak_bytes));
+ setTextAlignment(Receiver_NAKRate_Column, Qt::AlignRight);
+}
+
+typedef QMap<QString, LBMLBTRMReceiverTransportEntry *> LBMLBTRMReceiverTransportMap;
+typedef QMap<QString, LBMLBTRMReceiverTransportEntry *>::iterator LBMLBTRMReceiverTransportMapIterator;
+
+// A receiver (address) entry
+class LBMLBTRMReceiverEntry : public QTreeWidgetItem
+{
+ public:
+ LBMLBTRMReceiverEntry(const QString & receiver_address);
+ virtual ~LBMLBTRMReceiverEntry(void);
+ void processPacket(const packet_info * pinfo, const lbm_lbtrm_tap_info_t * tap_info);
+
+ private:
+ LBMLBTRMReceiverEntry(void);
+ void fillItem(void);
+ QString m_address;
+ QString m_transport;
+ guint64 m_nak_frames;
+ guint64 m_nak_count;
+ guint64 m_nak_bytes;
+ nstime_t m_first_frame_timestamp;
+ bool m_first_frame_timestamp_valid;
+ nstime_t m_last_frame_timestamp;
+ LBMLBTRMReceiverTransportMap m_transports;
+};
+
+LBMLBTRMReceiverEntry::LBMLBTRMReceiverEntry(const QString & receiver_address) :
+ QTreeWidgetItem(),
+ m_address(receiver_address),
+ m_nak_frames(0),
+ m_nak_count(0),
+ m_nak_bytes(0),
+ m_first_frame_timestamp_valid(false),
+ m_transports()
+{
+ m_first_frame_timestamp.secs = 0;
+ m_first_frame_timestamp.nsecs = 0;
+ m_last_frame_timestamp.secs = 0;
+ m_last_frame_timestamp.nsecs = 0;
+ setText(Receiver_AddressTransport_Column, m_address);
+}
+
+LBMLBTRMReceiverEntry::~LBMLBTRMReceiverEntry(void)
+{
+ for (LBMLBTRMReceiverTransportMapIterator it = m_transports.begin(); it != m_transports.end(); it++)
+ {
+ delete *it;
+ }
+ m_transports.clear();
+}
+
+void LBMLBTRMReceiverEntry::processPacket(const packet_info * pinfo, const lbm_lbtrm_tap_info_t * tap_info)
+{
+ LBMLBTRMReceiverTransportEntry * transport = NULL;
+ LBMLBTRMReceiverTransportMapIterator it;
+
+ if (m_first_frame_timestamp_valid)
+ {
+ if (nstime_cmp(&(pinfo->fd->abs_ts), &m_first_frame_timestamp) < 0)
+ {
+ nstime_copy(&(m_first_frame_timestamp), &(pinfo->fd->abs_ts));
+ }
+ }
+ else
+ {
+ nstime_copy(&(m_first_frame_timestamp), &(pinfo->fd->abs_ts));
+ m_first_frame_timestamp_valid = true;
+ }
+ if (nstime_cmp(&(pinfo->fd->abs_ts), &m_last_frame_timestamp) > 0)
+ {
+ nstime_copy(&(m_last_frame_timestamp), &(pinfo->fd->abs_ts));
+ }
+ if (tap_info->type == LBTRM_PACKET_TYPE_NAK)
+ {
+ m_nak_frames++;
+ m_nak_bytes += pinfo->fd->pkt_len;
+ m_nak_count += tap_info->num_sqns;
+ }
+
+ it = m_transports.find(tap_info->transport);
+ if (m_transports.end() == it)
+ {
+ transport = new LBMLBTRMReceiverTransportEntry(tap_info->transport);
+ m_transports.insert(tap_info->transport, transport);
+ addChild(transport);
+ sortChildren(Receiver_AddressTransport_Column, Qt::AscendingOrder);
+ }
+ else
+ {
+ transport = it.value();
+ }
+ fillItem();
+ transport->processPacket(pinfo, tap_info);
+}
+
+void LBMLBTRMReceiverEntry::fillItem(void)
+{
+ nstime_t delta;
+
+ nstime_delta(&delta, &m_last_frame_timestamp, &m_first_frame_timestamp);
+ setText(Receiver_NAKFrames_Column, QString("%1").arg(m_nak_frames));
+ setTextAlignment(Receiver_NAKFrames_Column, Qt::AlignRight);
+ setText(Receiver_NAKCount_Column, QString("%1").arg(m_nak_count));
+ setTextAlignment(Receiver_NAKCount_Column, Qt::AlignRight);
+ setText(Receiver_NAKBytes_Column, QString("%1").arg(m_nak_bytes));
+ setTextAlignment(Receiver_NAKBytes_Column, Qt::AlignRight);
+ setText(Receiver_NAKRate_Column, format_rate(delta, m_nak_bytes));
+ setTextAlignment(Receiver_NAKRate_Column, Qt::AlignRight);
+}
+
+typedef QMap<QString, LBMLBTRMReceiverEntry *> LBMLBTRMReceiverMap;
+typedef QMap<QString, LBMLBTRMReceiverEntry *>::iterator LBMLBTRMReceiverMapIterator;
+
+class LBMLBTRMTransportDialogInfo
+{
+ public:
+ LBMLBTRMTransportDialogInfo(void);
+ ~LBMLBTRMTransportDialogInfo(void);
+ void setDialog(LBMLBTRMTransportDialog * dialog);
+ LBMLBTRMTransportDialog * getDialog(void);
+ void processPacket(const packet_info * pinfo, const lbm_lbtrm_tap_info_t * tap_info);
+ void clearMaps(void);
+
+ private:
+ LBMLBTRMTransportDialog * m_dialog;
+ LBMLBTRMSourceMap m_sources;
+ LBMLBTRMReceiverMap m_receivers;
+};
+
+LBMLBTRMTransportDialogInfo::LBMLBTRMTransportDialogInfo(void) :
+ m_dialog(NULL),
+ m_sources(),
+ m_receivers()
+{
+}
+
+LBMLBTRMTransportDialogInfo::~LBMLBTRMTransportDialogInfo(void)
+{
+ clearMaps();
+}
+
+void LBMLBTRMTransportDialogInfo::setDialog(LBMLBTRMTransportDialog * dialog)
+{
+ m_dialog = dialog;
+}
+
+LBMLBTRMTransportDialog * LBMLBTRMTransportDialogInfo::getDialog(void)
+{
+ return (m_dialog);
+}
+
+void LBMLBTRMTransportDialogInfo::processPacket(const packet_info * pinfo, const lbm_lbtrm_tap_info_t * tap_info)
+{
+ switch (tap_info->type)
+ {
+ case LBTRM_PACKET_TYPE_DATA:
+ case LBTRM_PACKET_TYPE_SM:
+ case LBTRM_PACKET_TYPE_NCF:
+ {
+ LBMLBTRMSourceEntry * source = NULL;
+ LBMLBTRMSourceMapIterator it;
+ QString src_address = QString(address_to_str(wmem_packet_scope(), &(pinfo->src)));
+
+ it = m_sources.find(src_address);
+ if (m_sources.end() == it)
+ {
+ QTreeWidgetItem * parent = NULL;
+ Ui::LBMLBTRMTransportDialog * ui = NULL;
+
+ source = new LBMLBTRMSourceEntry(src_address);
+ it = m_sources.insert(src_address, source);
+ ui = m_dialog->getUI();
+ ui->sources_TreeWidget->addTopLevelItem(source);
+ parent = ui->sources_TreeWidget->invisibleRootItem();
+ parent->sortChildren(Source_AddressTransport_Column, Qt::AscendingOrder);
+ ui->sources_TreeWidget->resizeColumnToContents(Source_AddressTransport_Column);
+ }
+ else
+ {
+ source = it.value();
+ }
+ source->processPacket(pinfo, tap_info);
+ }
+ break;
+ case LBTRM_PACKET_TYPE_NAK:
+ {
+ LBMLBTRMReceiverEntry * receiver = NULL;
+ LBMLBTRMReceiverMapIterator it;
+ QString src_address = QString(address_to_str(wmem_packet_scope(), &(pinfo->src)));
+
+ it = m_receivers.find(src_address);
+ if (m_receivers.end() == it)
+ {
+ QTreeWidgetItem * parent = NULL;
+ Ui::LBMLBTRMTransportDialog * ui = NULL;
+
+ receiver = new LBMLBTRMReceiverEntry(src_address);
+ it = m_receivers.insert(src_address, receiver);
+ ui = m_dialog->getUI();
+ ui->receivers_TreeWidget->addTopLevelItem(receiver);
+ parent = ui->receivers_TreeWidget->invisibleRootItem();
+ parent->sortChildren(Receiver_AddressTransport_Column, Qt::AscendingOrder);
+ ui->receivers_TreeWidget->resizeColumnToContents(Receiver_AddressTransport_Column);
+ }
+ else
+ {
+ receiver = it.value();
+ }
+ receiver->processPacket(pinfo, tap_info);
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+void LBMLBTRMTransportDialogInfo::clearMaps(void)
+{
+ for (LBMLBTRMSourceMapIterator it = m_sources.begin(); it != m_sources.end(); it++)
+ {
+ delete *it;
+ }
+ m_sources.clear();
+
+ for (LBMLBTRMReceiverMapIterator it = m_receivers.begin(); it != m_receivers.end(); it++)
+ {
+ delete *it;
+ }
+ m_receivers.clear();
+}
+
+LBMLBTRMTransportDialog::LBMLBTRMTransportDialog(QWidget * parent, capture_file * cfile) :
+ QDialog(parent),
+ m_ui(new Ui::LBMLBTRMTransportDialog),
+ m_dialog_info(NULL),
+ m_capture_file(cfile),
+ m_current_source_transport(NULL),
+ m_current_receiver_transport(NULL),
+ m_source_context_menu(NULL),
+ m_source_header(NULL)
+{
+ m_ui->setupUi(this);
+ m_dialog_info = new LBMLBTRMTransportDialogInfo();
+
+ m_ui->tabWidget->setCurrentIndex(0);
+ m_ui->sources_detail_ComboBox->setCurrentIndex(0);
+ m_ui->sources_detail_transport_Label->setText(QString(" "));
+ m_ui->receivers_detail_transport_Label->setText(QString(" "));
+ m_ui->stackedWidget->setCurrentIndex(0);
+
+ m_source_header = m_ui->sources_TreeWidget->header();
+ m_source_context_menu = new QMenu(m_source_header);
+
+ m_source_context_menu->addAction(m_ui->action_SourceAutoResizeColumns);
+ connect(m_ui->action_SourceAutoResizeColumns, SIGNAL(triggered()), this, SLOT(actionSourceAutoResizeColumns_triggered()));
+ m_source_context_menu->addSeparator();
+
+ m_ui->action_SourceDataFrames->setChecked(true);
+ m_source_context_menu->addAction(m_ui->action_SourceDataFrames);
+ connect(m_ui->action_SourceDataFrames, SIGNAL(triggered(bool)), this, SLOT(actionSourceDataFrames_triggered(bool)));
+ m_ui->action_SourceDataBytes->setChecked(true);
+ m_source_context_menu->addAction(m_ui->action_SourceDataBytes);
+ connect(m_ui->action_SourceDataBytes, SIGNAL(triggered(bool)), this, SLOT(actionSourceDataBytes_triggered(bool)));
+ m_ui->action_SourceDataFramesBytes->setChecked(false);
+ m_source_context_menu->addAction(m_ui->action_SourceDataFramesBytes);
+ connect(m_ui->action_SourceDataFramesBytes, SIGNAL(triggered(bool)), this, SLOT(actionSourceDataFramesBytes_triggered(bool)));
+ m_ui->action_SourceDataRate->setChecked(true);
+ m_source_context_menu->addAction(m_ui->action_SourceDataRate);
+ connect(m_ui->action_SourceDataRate, SIGNAL(triggered(bool)), this, SLOT(actionSourceDataRate_triggered(bool)));
+
+ m_ui->action_SourceRXDataFrames->setChecked(true);
+ m_source_context_menu->addAction(m_ui->action_SourceRXDataFrames);
+ connect(m_ui->action_SourceRXDataFrames, SIGNAL(triggered(bool)), this, SLOT(actionSourceRXDataFrames_triggered(bool)));
+ m_ui->action_SourceRXDataBytes->setChecked(true);
+ m_source_context_menu->addAction(m_ui->action_SourceRXDataBytes);
+ connect(m_ui->action_SourceRXDataBytes, SIGNAL(triggered(bool)), this, SLOT(actionSourceRXDataBytes_triggered(bool)));
+ m_ui->action_SourceRXDataFramesBytes->setChecked(false);
+ m_source_context_menu->addAction(m_ui->action_SourceRXDataFramesBytes);
+ connect(m_ui->action_SourceRXDataFramesBytes, SIGNAL(triggered(bool)), this, SLOT(actionSourceRXDataFramesBytes_triggered(bool)));
+ m_ui->action_SourceRXDataRate->setChecked(true);
+ m_source_context_menu->addAction(m_ui->action_SourceRXDataRate);
+ connect(m_ui->action_SourceRXDataRate, SIGNAL(triggered(bool)), this, SLOT(actionSourceRXDataRate_triggered(bool)));
+
+ m_ui->action_SourceNCFFrames->setChecked(true);
+ m_source_context_menu->addAction(m_ui->action_SourceNCFFrames);
+ connect(m_ui->action_SourceNCFFrames, SIGNAL(triggered(bool)), this, SLOT(actionSourceNCFFrames_triggered(bool)));
+ m_ui->action_SourceNCFCount->setChecked(true);
+ m_source_context_menu->addAction(m_ui->action_SourceNCFCount);
+ connect(m_ui->action_SourceNCFCount, SIGNAL(triggered(bool)), this, SLOT(actionSourceNCFCount_triggered(bool)));
+ m_ui->action_SourceNCFBytes->setChecked(true);
+ m_source_context_menu->addAction(m_ui->action_SourceNCFBytes);
+ connect(m_ui->action_SourceNCFBytes, SIGNAL(triggered(bool)), this, SLOT(actionSourceNCFBytes_triggered(bool)));
+ m_ui->action_SourceNCFFramesBytes->setChecked(false);
+ m_source_context_menu->addAction(m_ui->action_SourceNCFFramesBytes);
+ connect(m_ui->action_SourceNCFFramesBytes, SIGNAL(triggered(bool)), this, SLOT(actionSourceNCFFramesBytes_triggered(bool)));
+ m_ui->action_SourceNCFCountBytes->setChecked(false);
+ m_source_context_menu->addAction(m_ui->action_SourceNCFCountBytes);
+ connect(m_ui->action_SourceNCFCountBytes, SIGNAL(triggered(bool)), this, SLOT(actionSourceNCFCountBytes_triggered(bool)));
+ m_ui->action_SourceNCFFramesCount->setChecked(false);
+ m_source_context_menu->addAction(m_ui->action_SourceNCFFramesCount);
+ connect(m_ui->action_SourceNCFFramesCount, SIGNAL(triggered(bool)), this, SLOT(actionSourceNCFFramesCount_triggered(bool)));
+ m_ui->action_SourceNCFFramesCountBytes->setChecked(false);
+ m_source_context_menu->addAction(m_ui->action_SourceNCFFramesCountBytes);
+ connect(m_ui->action_SourceNCFFramesCountBytes, SIGNAL(triggered(bool)), this, SLOT(actionSourceNCFFramesCountBytes_triggered(bool)));
+ m_ui->action_SourceNCFRate->setChecked(true);
+ m_source_context_menu->addAction(m_ui->action_SourceNCFRate);
+ connect(m_ui->action_SourceNCFRate, SIGNAL(triggered(bool)), this, SLOT(actionSourceNCFRate_triggered(bool)));
+
+ m_ui->action_SourceSMFrames->setChecked(true);
+ m_source_context_menu->addAction(m_ui->action_SourceSMFrames);
+ connect(m_ui->action_SourceSMFrames, SIGNAL(triggered(bool)), this, SLOT(actionSourceSMFrames_triggered(bool)));
+ m_ui->action_SourceSMBytes->setChecked(true);
+ m_source_context_menu->addAction(m_ui->action_SourceSMBytes);
+ connect(m_ui->action_SourceSMBytes, SIGNAL(triggered(bool)), this, SLOT(actionSourceSMBytes_triggered(bool)));
+ m_ui->action_SourceSMFramesBytes->setChecked(false);
+ m_source_context_menu->addAction(m_ui->action_SourceSMFramesBytes);
+ connect(m_ui->action_SourceSMFramesBytes, SIGNAL(triggered(bool)), this, SLOT(actionSourceSMFramesBytes_triggered(bool)));
+ m_ui->action_SourceSMRate->setChecked(true);
+ m_source_context_menu->addAction(m_ui->action_SourceSMRate);
+ connect(m_ui->action_SourceSMRate, SIGNAL(triggered(bool)), this, SLOT(actionSourceSMRate_triggered(bool)));
+
+ m_source_header->setContextMenuPolicy(Qt::CustomContextMenu);
+ connect(m_source_header, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(custom_source_context_menuRequested(const QPoint &)));
+
+ m_ui->sources_TreeWidget->setColumnHidden(Source_DataFramesBytes_Column, true);
+ m_ui->sources_TreeWidget->setColumnHidden(Source_RXDataFramesBytes_Column, true);
+ m_ui->sources_TreeWidget->setColumnHidden(Source_NCFFramesBytes_Column, true);
+ m_ui->sources_TreeWidget->setColumnHidden(Source_NCFCountBytes_Column, true);
+ m_ui->sources_TreeWidget->setColumnHidden(Source_NCFFramesCount_Column, true);
+ m_ui->sources_TreeWidget->setColumnHidden(Source_NCFFramesCountBytes_Column, true);
+ m_ui->sources_TreeWidget->setColumnHidden(Source_SMFramesBytes_Column, true);
+
+ connect(this, SIGNAL(accepted()), this, SLOT(closeDialog()));
+ connect(this, SIGNAL(rejected()), this, SLOT(closeDialog()));
+ fillTree();
+}
+
+LBMLBTRMTransportDialog::~LBMLBTRMTransportDialog(void)
+{
+ resetSourcesDetail();
+ resetSources();
+ resetReceiversDetail();
+ resetReceivers();
+ if (m_dialog_info != NULL)
+ {
+ delete m_dialog_info;
+ m_dialog_info = NULL;
+ }
+ delete m_source_context_menu;
+ m_source_context_menu = NULL;
+ delete m_ui;
+ m_ui = NULL;
+ m_capture_file = NULL;
+}
+
+void LBMLBTRMTransportDialog::setCaptureFile(capture_file * cfile)
+{
+ if (cfile == NULL) // We only want to know when the file closes.
+ {
+ m_capture_file = NULL;
+ m_ui->displayFilterLineEdit->setEnabled(false);
+ m_ui->applyFilterButton->setEnabled(false);
+ }
+}
+
+void LBMLBTRMTransportDialog::resetSources(void)
+{
+ while (m_ui->sources_TreeWidget->takeTopLevelItem(0) != NULL)
+ {}
+}
+
+void LBMLBTRMTransportDialog::resetReceivers(void)
+{
+ while (m_ui->receivers_TreeWidget->takeTopLevelItem(0) != NULL)
+ {}
+}
+
+void LBMLBTRMTransportDialog::resetSourcesDetail(void)
+{
+ while (m_ui->sources_detail_sqn_TreeWidget->takeTopLevelItem(0) != NULL)
+ {}
+ while (m_ui->sources_detail_ncf_sqn_TreeWidget->takeTopLevelItem(0) != NULL)
+ {}
+ m_ui->sources_detail_transport_Label->setText(QString(" "));
+ m_current_source_transport = NULL;
+}
+
+void LBMLBTRMTransportDialog::resetReceiversDetail(void)
+{
+ while (m_ui->receivers_detail_TreeWidget->takeTopLevelItem(0) != NULL)
+ {}
+ m_ui->receivers_detail_transport_Label->setText(QString(" "));
+ m_current_receiver_transport = NULL;
+}
+
+void LBMLBTRMTransportDialog::fillTree(void)
+{
+ GString * error_string;
+
+ if (m_capture_file == NULL)
+ {
+ return;
+ }
+ m_dialog_info->setDialog(this);
+
+ error_string = register_tap_listener("lbtrm",
+ (void *)m_dialog_info,
+ m_ui->displayFilterLineEdit->text().toUtf8().constData(),
+ TL_REQUIRES_COLUMNS,
+ resetTap,
+ tapPacket,
+ drawTreeItems);
+ if (error_string)
+ {
+ QMessageBox::critical(this, tr("LBT-RM Statistics failed to attach to tap"),
+ error_string->str);
+ g_string_free(error_string, TRUE);
+ reject();
+ }
+
+ cf_retap_packets(m_capture_file);
+ drawTreeItems(&m_dialog_info);
+ remove_tap_listener((void *)m_dialog_info);
+}
+
+void LBMLBTRMTransportDialog::resetTap(void * tap_data)
+{
+ LBMLBTRMTransportDialogInfo * info = (LBMLBTRMTransportDialogInfo *) tap_data;
+ LBMLBTRMTransportDialog * dialog = info->getDialog();
+ if (dialog == NULL)
+ {
+ return;
+ }
+ dialog->resetSourcesDetail();
+ dialog->resetSources();
+ dialog->resetReceiversDetail();
+ dialog->resetReceivers();
+ info->clearMaps();
+}
+
+gboolean LBMLBTRMTransportDialog::tapPacket(void * tap_data, packet_info * pinfo, epan_dissect_t * edt, const void * tap_info)
+{
+ Q_UNUSED(edt)
+
+ if (pinfo->fd->flags.passed_dfilter == 1)
+ {
+ const lbm_lbtrm_tap_info_t * tapinfo = (const lbm_lbtrm_tap_info_t *)tap_info;
+ LBMLBTRMTransportDialogInfo * info = (LBMLBTRMTransportDialogInfo *)tap_data;
+
+ info->processPacket(pinfo, tapinfo);
+ }
+ return (TRUE);
+}
+
+void LBMLBTRMTransportDialog::drawTreeItems(void * tap_data)
+{
+ Q_UNUSED(tap_data)
+}
+
+void LBMLBTRMTransportDialog::on_applyFilterButton_clicked(void)
+{
+ fillTree();
+}
+
+void LBMLBTRMTransportDialog::closeDialog(void)
+{
+ delete this;
+}
+
+void LBMLBTRMTransportDialog::sourcesDetailCurrentChanged(int index)
+{
+ // Index 0: Data
+ // Index 1: RX data
+ // Index 2: NCF
+ // Index 3: SM
+ switch (index)
+ {
+ case 0:
+ case 1:
+ case 3:
+ m_ui->stackedWidget->setCurrentIndex(0);
+ break;
+ case 2:
+ m_ui->stackedWidget->setCurrentIndex(1);
+ break;
+ default:
+ return;
+ }
+ sourcesItemClicked(m_current_source_transport, 0);
+}
+
+void LBMLBTRMTransportDialog::sourcesItemClicked(QTreeWidgetItem * item, int column)
+{
+ Q_UNUSED(column)
+
+ LBMLBTRMSourceTransportEntry * transport = dynamic_cast<LBMLBTRMSourceTransportEntry *>(item);
+
+ resetSourcesDetail();
+ if (transport == NULL)
+ {
+ // Must be a source item, ignore it?
+ return;
+ }
+ m_current_source_transport = transport;
+ m_ui->sources_detail_transport_Label->setText(transport->m_transport);
+ int cur_idx = m_ui->sources_detail_ComboBox->currentIndex();
+ switch (cur_idx)
+ {
+ case 0:
+ loadSourceDataDetails(transport);
+ break;
+ case 1:
+ loadSourceRXDataDetails(transport);
+ break;
+ case 2:
+ loadSourceNCFDetails(transport);
+ break;
+ case 3:
+ loadSourceSMDetails(transport);
+ break;
+ default:
+ break;
+ }
+}
+
+void LBMLBTRMTransportDialog::loadSourceDataDetails(LBMLBTRMSourceTransportEntry * transport)
+{
+ for (LBMLBTRMSQNMapIterator it = transport->m_data_sqns.begin(); it != transport->m_data_sqns.end(); it++)
+ {
+ LBMLBTRMSQNEntry * sqn = it.value();
+ m_ui->sources_detail_sqn_TreeWidget->addTopLevelItem(sqn);
+ }
+}
+
+void LBMLBTRMTransportDialog::loadSourceRXDataDetails(LBMLBTRMSourceTransportEntry * transport)
+{
+ for (LBMLBTRMSQNMapIterator it = transport->m_rx_data_sqns.begin(); it != transport->m_rx_data_sqns.end(); it++)
+ {
+ LBMLBTRMSQNEntry * sqn = it.value();
+ m_ui->sources_detail_sqn_TreeWidget->addTopLevelItem(sqn);
+ }
+}
+
+void LBMLBTRMTransportDialog::loadSourceNCFDetails(LBMLBTRMSourceTransportEntry * transport)
+{
+ for (LBMLBTRMNCFSQNMapIterator it = transport->m_ncf_sqns.begin(); it != transport->m_ncf_sqns.end(); it++)
+ {
+ LBMLBTRMNCFSQNEntry * sqn = it.value();
+ m_ui->sources_detail_ncf_sqn_TreeWidget->addTopLevelItem(sqn);
+ }
+}
+
+void LBMLBTRMTransportDialog::loadSourceSMDetails(LBMLBTRMSourceTransportEntry * transport)
+{
+ for (LBMLBTRMSQNMapIterator it = transport->m_sm_sqns.begin(); it != transport->m_sm_sqns.end(); it++)
+ {
+ LBMLBTRMSQNEntry * sqn = it.value();
+ m_ui->sources_detail_sqn_TreeWidget->addTopLevelItem(sqn);
+ }
+}
+
+void LBMLBTRMTransportDialog::receiversItemClicked(QTreeWidgetItem * item, int column)
+{
+ Q_UNUSED(column)
+
+ LBMLBTRMReceiverTransportEntry * transport = dynamic_cast<LBMLBTRMReceiverTransportEntry *>(item);
+
+ resetReceiversDetail();
+ if (transport == NULL)
+ {
+ // Must be a receiver item, ignore it?
+ return;
+ }
+ m_current_receiver_transport = transport;
+ m_ui->receivers_detail_transport_Label->setText(transport->m_transport);
+ loadReceiverNAKDetails(transport);
+}
+
+void LBMLBTRMTransportDialog::loadReceiverNAKDetails(LBMLBTRMReceiverTransportEntry * transport)
+{
+ for (LBMLBTRMSQNMapIterator it = transport->m_nak_sqns.begin(); it != transport->m_nak_sqns.end(); it++)
+ {
+ LBMLBTRMSQNEntry * sqn = it.value();
+ m_ui->receivers_detail_TreeWidget->addTopLevelItem(sqn);
+ }
+}
+
+void LBMLBTRMTransportDialog::sourcesDetailItemDoubleClicked(QTreeWidgetItem * item, int column)
+{
+ Q_UNUSED(column)
+
+ LBMLBTRMFrameEntry * frame = dynamic_cast<LBMLBTRMFrameEntry *>(item);
+ if (frame == NULL)
+ {
+ // Must have double-clicked on something other than an expanded frame entry
+ return;
+ }
+ emit goToPacket((int)frame->getFrame());
+}
+
+void LBMLBTRMTransportDialog::receiversDetailItemDoubleClicked(QTreeWidgetItem * item, int column)
+{
+ Q_UNUSED(column)
+
+ LBMLBTRMFrameEntry * frame = dynamic_cast<LBMLBTRMFrameEntry *>(item);
+ if (frame == NULL)
+ {
+ // Must have double-clicked on something other than an expanded frame entry
+ return;
+ }
+ emit goToPacket((int)frame->getFrame());
+}
+
+void LBMLBTRMTransportDialog::custom_source_context_menuRequested(const QPoint & pos)
+{
+ m_source_context_menu->exec(m_source_header->mapToGlobal(pos));
+}
+
+void LBMLBTRMTransportDialog::actionSourceDataFrames_triggered(bool checked)
+{
+ m_ui->sources_TreeWidget->setColumnHidden(Source_DataFrames_Column, !checked);
+}
+
+void LBMLBTRMTransportDialog::actionSourceDataBytes_triggered(bool checked)
+{
+ m_ui->sources_TreeWidget->setColumnHidden(Source_DataBytes_Column, !checked);
+}
+
+void LBMLBTRMTransportDialog::actionSourceDataFramesBytes_triggered(bool checked)
+{
+ m_ui->sources_TreeWidget->setColumnHidden(Source_DataFramesBytes_Column, !checked);
+}
+
+void LBMLBTRMTransportDialog::actionSourceDataRate_triggered(bool checked)
+{
+ m_ui->sources_TreeWidget->setColumnHidden(Source_DataRate_Column, !checked);
+}
+
+void LBMLBTRMTransportDialog::actionSourceRXDataFrames_triggered(bool checked)
+{
+ m_ui->sources_TreeWidget->setColumnHidden(Source_RXDataFrames_Column, !checked);
+}
+
+void LBMLBTRMTransportDialog::actionSourceRXDataBytes_triggered(bool checked)
+{
+ m_ui->sources_TreeWidget->setColumnHidden(Source_RXDataBytes_Column, !checked);
+}
+
+void LBMLBTRMTransportDialog::actionSourceRXDataFramesBytes_triggered(bool checked)
+{
+ m_ui->sources_TreeWidget->setColumnHidden(Source_RXDataFramesBytes_Column, !checked);
+}
+
+void LBMLBTRMTransportDialog::actionSourceRXDataRate_triggered(bool checked)
+{
+ m_ui->sources_TreeWidget->setColumnHidden(Source_RXDataRate_Column, !checked);
+}
+
+void LBMLBTRMTransportDialog::actionSourceNCFFrames_triggered(bool checked)
+{
+ m_ui->sources_TreeWidget->setColumnHidden(Source_NCFFrames_Column, !checked);
+}
+
+void LBMLBTRMTransportDialog::actionSourceNCFCount_triggered(bool checked)
+{
+ m_ui->sources_TreeWidget->setColumnHidden(Source_NCFCount_Column, !checked);
+}
+
+void LBMLBTRMTransportDialog::actionSourceNCFBytes_triggered(bool checked)
+{
+ m_ui->sources_TreeWidget->setColumnHidden(Source_NCFFrames_Column, !checked);
+}
+
+void LBMLBTRMTransportDialog::actionSourceNCFFramesBytes_triggered(bool checked)
+{
+ m_ui->sources_TreeWidget->setColumnHidden(Source_NCFFramesBytes_Column, !checked);
+}
+
+void LBMLBTRMTransportDialog::actionSourceNCFCountBytes_triggered(bool checked)
+{
+ m_ui->sources_TreeWidget->setColumnHidden(Source_NCFCountBytes_Column, !checked);
+}
+
+void LBMLBTRMTransportDialog::actionSourceNCFFramesCount_triggered(bool checked)
+{
+ m_ui->sources_TreeWidget->setColumnHidden(Source_NCFFramesCount_Column, !checked);
+}
+
+void LBMLBTRMTransportDialog::actionSourceNCFFramesCountBytes_triggered(bool checked)
+{
+ m_ui->sources_TreeWidget->setColumnHidden(Source_NCFFramesCountBytes_Column, !checked);
+}
+
+void LBMLBTRMTransportDialog::actionSourceNCFRate_triggered(bool checked)
+{
+ m_ui->sources_TreeWidget->setColumnHidden(Source_NCFRate_Column, !checked);
+}
+
+void LBMLBTRMTransportDialog::actionSourceSMFrames_triggered(bool checked)
+{
+ m_ui->sources_TreeWidget->setColumnHidden(Source_SMFrames_Column, !checked);
+}
+
+void LBMLBTRMTransportDialog::actionSourceSMBytes_triggered(bool checked)
+{
+ m_ui->sources_TreeWidget->setColumnHidden(Source_SMBytes_Column, !checked);
+}
+
+void LBMLBTRMTransportDialog::actionSourceSMFramesBytes_triggered(bool checked)
+{
+ m_ui->sources_TreeWidget->setColumnHidden(Source_SMFramesBytes_Column, !checked);
+}
+
+void LBMLBTRMTransportDialog::actionSourceSMRate_triggered(bool checked)
+{
+ m_ui->sources_TreeWidget->setColumnHidden(Source_SMRate_Column, !checked);
+}
+
+void LBMLBTRMTransportDialog::actionSourceAutoResizeColumns_triggered(void)
+{
+ m_ui->sources_TreeWidget->resizeColumnToContents(Source_AddressTransport_Column);
+ m_ui->sources_TreeWidget->resizeColumnToContents(Source_DataFrames_Column);
+ m_ui->sources_TreeWidget->resizeColumnToContents(Source_DataBytes_Column);
+ m_ui->sources_TreeWidget->resizeColumnToContents(Source_DataFramesBytes_Column);
+ m_ui->sources_TreeWidget->resizeColumnToContents(Source_DataRate_Column);
+ m_ui->sources_TreeWidget->resizeColumnToContents(Source_RXDataFrames_Column);
+ m_ui->sources_TreeWidget->resizeColumnToContents(Source_RXDataBytes_Column);
+ m_ui->sources_TreeWidget->resizeColumnToContents(Source_RXDataFramesBytes_Column);
+ m_ui->sources_TreeWidget->resizeColumnToContents(Source_RXDataRate_Column);
+ m_ui->sources_TreeWidget->resizeColumnToContents(Source_NCFFrames_Column);
+ m_ui->sources_TreeWidget->resizeColumnToContents(Source_NCFCount_Column);
+ m_ui->sources_TreeWidget->resizeColumnToContents(Source_NCFBytes_Column);
+ m_ui->sources_TreeWidget->resizeColumnToContents(Source_NCFFramesBytes_Column);
+ m_ui->sources_TreeWidget->resizeColumnToContents(Source_NCFCountBytes_Column);
+ m_ui->sources_TreeWidget->resizeColumnToContents(Source_NCFFramesCount_Column);
+ m_ui->sources_TreeWidget->resizeColumnToContents(Source_NCFFramesCountBytes_Column);
+ m_ui->sources_TreeWidget->resizeColumnToContents(Source_NCFRate_Column);
+ m_ui->sources_TreeWidget->resizeColumnToContents(Source_SMFrames_Column);
+ m_ui->sources_TreeWidget->resizeColumnToContents(Source_SMBytes_Column);
+ m_ui->sources_TreeWidget->resizeColumnToContents(Source_SMFramesBytes_Column);
+ m_ui->sources_TreeWidget->resizeColumnToContents(Source_SMRate_Column);
+}
+
+/*
+ * Editor modelines - http://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vi: set shiftwidth=4 tabstop=4 expandtab:
+ * :indentSize=4:tabSize=4:noTabs=true:
+ */
diff --git a/ui/qt/lbm_lbtrm_transport_dialog.h b/ui/qt/lbm_lbtrm_transport_dialog.h
new file mode 100644
index 0000000000..c46898e549
--- /dev/null
+++ b/ui/qt/lbm_lbtrm_transport_dialog.h
@@ -0,0 +1,132 @@
+/* lbm_lbtrm_transport_dialog.h
+ *
+ * Copyright (c) 2005-2014 Informatica Corporation. All Rights Reserved.
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef LBM_LBTRM_TRANSPORT_DIALOG_H
+#define LBM_LBTRM_TRANSPORT_DIALOG_H
+
+#include "config.h"
+
+#include <glib.h>
+
+#include "cfile.h"
+#include <epan/packet_info.h>
+#include <QDialog>
+#include <QTreeWidgetItem>
+
+namespace Ui
+{
+ class LBMLBTRMTransportDialog;
+}
+
+class LBMLBTRMTransportDialogInfo;
+class LBMLBTRMSourceTransportEntry;
+class LBMLBTRMReceiverTransportEntry;
+
+class LBMLBTRMTransportDialog : public QDialog
+{
+ Q_OBJECT
+
+ public:
+ explicit LBMLBTRMTransportDialog(QWidget * parent = 0, capture_file * cfile = NULL);
+ Ui::LBMLBTRMTransportDialog * getUI(void)
+ {
+ return (m_ui);
+ }
+ public slots:
+ void setCaptureFile(capture_file * cfile);
+
+ signals:
+ void goToPacket(int PacketNum);
+
+ private:
+ Ui::LBMLBTRMTransportDialog * m_ui;
+ LBMLBTRMTransportDialogInfo * m_dialog_info;
+ capture_file * m_capture_file;
+ LBMLBTRMSourceTransportEntry * m_current_source_transport;
+ LBMLBTRMReceiverTransportEntry * m_current_receiver_transport;
+ QMenu * m_source_context_menu;
+ QHeaderView * m_source_header;
+
+ virtual ~LBMLBTRMTransportDialog(void);
+ void resetSources(void);
+ void resetReceivers(void);
+ void resetSourcesDetail(void);
+ void resetReceiversDetail(void);
+ void fillTree(void);
+ static void resetTap(void * tap_data);
+ static gboolean tapPacket(void * tap_data, packet_info * pinfo, epan_dissect_t * edt, const void * stream_info);
+ static void drawTreeItems(void * tap_data);
+ void loadSourceDataDetails(LBMLBTRMSourceTransportEntry * transport);
+ void loadSourceRXDataDetails(LBMLBTRMSourceTransportEntry * transport);
+ void loadSourceNCFDetails(LBMLBTRMSourceTransportEntry * transport);
+ void loadSourceSMDetails(LBMLBTRMSourceTransportEntry * transport);
+ void loadSourceRSTDetails(LBMLBTRMSourceTransportEntry * transport);
+ void loadReceiverNAKDetails(LBMLBTRMReceiverTransportEntry * transport);
+
+ private slots:
+ void closeDialog(void);
+ void on_applyFilterButton_clicked(void);
+
+ void sourcesDetailCurrentChanged(int Index);
+ void sourcesItemClicked(QTreeWidgetItem * item, int column);
+ void receiversItemClicked(QTreeWidgetItem * item, int column);
+ void sourcesDetailItemDoubleClicked(QTreeWidgetItem * item, int column);
+ void receiversDetailItemDoubleClicked(QTreeWidgetItem * item, int column);
+ void actionSourceDataFrames_triggered(bool checked);
+ void actionSourceDataBytes_triggered(bool checked);
+ void actionSourceDataFramesBytes_triggered(bool checked);
+ void actionSourceDataRate_triggered(bool checked);
+ void actionSourceRXDataFrames_triggered(bool checked);
+ void actionSourceRXDataBytes_triggered(bool checked);
+ void actionSourceRXDataFramesBytes_triggered(bool checked);
+ void actionSourceRXDataRate_triggered(bool checked);
+ void actionSourceNCFFrames_triggered(bool checked);
+ void actionSourceNCFCount_triggered(bool checked);
+ void actionSourceNCFBytes_triggered(bool checked);
+ void actionSourceNCFFramesBytes_triggered(bool checked);
+ void actionSourceNCFCountBytes_triggered(bool checked);
+ void actionSourceNCFFramesCount_triggered(bool checked);
+ void actionSourceNCFFramesCountBytes_triggered(bool checked);
+ void actionSourceNCFRate_triggered(bool checked);
+ void actionSourceSMFrames_triggered(bool checked);
+ void actionSourceSMBytes_triggered(bool checked);
+ void actionSourceSMFramesBytes_triggered(bool checked);
+ void actionSourceSMRate_triggered(bool checked);
+ void actionSourceAutoResizeColumns_triggered(void);
+ void custom_source_context_menuRequested(const QPoint & pos);
+};
+
+#endif
+
+/*
+ * Editor modelines - http://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vi: set shiftwidth=4 tabstop=4 expandtab:
+ * :indentSize=4:tabSize=4:noTabs=true:
+ */
diff --git a/ui/qt/lbm_lbtrm_transport_dialog.ui b/ui/qt/lbm_lbtrm_transport_dialog.ui
new file mode 100644
index 0000000000..c24057cf96
--- /dev/null
+++ b/ui/qt/lbm_lbtrm_transport_dialog.ui
@@ -0,0 +1,836 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>LBMLBTRMTransportDialog</class>
+ <widget class="QDialog" name="LBMLBTRMTransportDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>841</width>
+ <height>563</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>LBTRM Transport Statistics</string>
+ </property>
+ <property name="sizeGripEnabled">
+ <bool>true</bool>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QTabWidget" name="tabWidget">
+ <property name="currentIndex">
+ <number>0</number>
+ </property>
+ <widget class="QWidget" name="sourcesTab">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <attribute name="title">
+ <string>Sources</string>
+ </attribute>
+ <layout class="QHBoxLayout" name="horizontalLayout_5">
+ <item>
+ <widget class="QSplitter" name="splitter">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="handleWidth">
+ <number>10</number>
+ </property>
+ <widget class="QTreeWidget" name="sources_TreeWidget">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16777215</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <attribute name="headerDefaultSectionSize">
+ <number>80</number>
+ </attribute>
+ <column>
+ <property name="text">
+ <string>Address/Transport</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Data frames</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Data bytes</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Data frames/bytes</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Data rate</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>RX data frames</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>RX data bytes</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>RX data frames/bytes</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>RX data rate</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>NCF frames</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>NCF count</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>NCF bytes</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>NCF frames/bytes</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>NCF count/bytes</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>NCF frames/count</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>NCF frames/count/bytes</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>NCF rate</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>SM frames</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>SM bytes</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>SM frames/bytes</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>SM rate</string>
+ </property>
+ </column>
+ </widget>
+ <widget class="QWidget" name="layoutWidget">
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>Show</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="sources_detail_ComboBox">
+ <item>
+ <property name="text">
+ <string>Data</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>RX Data</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>NCF</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>SM</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_3">
+ <property name="text">
+ <string>sequence numbers for transport</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="sources_detail_transport_Label">
+ <property name="text">
+ <string>XXXXX:XXX.XXX.XXX.XXX:XXXXX:XXXXXXXX:XXX.XXX.XXX.XXX:XXXXX</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QStackedWidget" name="stackedWidget">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="lineWidth">
+ <number>1</number>
+ </property>
+ <property name="currentIndex">
+ <number>0</number>
+ </property>
+ <widget class="QWidget" name="sources_detail_sqn_page">
+ <layout class="QHBoxLayout" name="horizontalLayout_4">
+ <item>
+ <widget class="QTreeWidget" name="sources_detail_sqn_TreeWidget">
+ <column>
+ <property name="text">
+ <string>SQN</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Count</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Frame</string>
+ </property>
+ </column>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="sources_detail_ncf_sqn_page">
+ <layout class="QHBoxLayout" name="horizontalLayout_6">
+ <item>
+ <widget class="QTreeWidget" name="sources_detail_ncf_sqn_TreeWidget">
+ <column>
+ <property name="text">
+ <string>SQN/Reason</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Count</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Frame</string>
+ </property>
+ </column>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="receiversTab">
+ <attribute name="title">
+ <string>Receivers</string>
+ </attribute>
+ <layout class="QVBoxLayout" name="verticalLayout_4">
+ <item>
+ <widget class="QSplitter" name="splitter_2">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="handleWidth">
+ <number>10</number>
+ </property>
+ <widget class="QTreeWidget" name="receivers_TreeWidget">
+ <column>
+ <property name="text">
+ <string>Address/Transport</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>NAK frames</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>NAK count</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>NAK bytes</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>NAK rate</string>
+ </property>
+ </column>
+ </widget>
+ <widget class="QWidget" name="layoutWidget_2">
+ <layout class="QVBoxLayout" name="verticalLayout_3">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_3">
+ <item>
+ <widget class="QLabel" name="label_4">
+ <property name="text">
+ <string>NAK sequence numbers for transport</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="receivers_detail_transport_Label">
+ <property name="text">
+ <string>XXXXX:XXX.XXX.XXX.XXX:XXXXX:XXXXXXXX:XXX.XXX.XXX.XXX:XXXXX</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>10</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QTreeWidget" name="receivers_detail_TreeWidget">
+ <column>
+ <property name="text">
+ <string>SQN</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Count</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Frame</string>
+ </property>
+ </column>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Display filter:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="DisplayFilterEdit" name="displayFilterLineEdit"/>
+ </item>
+ <item>
+ <widget class="QPushButton" name="applyFilterButton">
+ <property name="toolTip">
+ <string>Regenerate statistics using this display filter</string>
+ </property>
+ <property name="text">
+ <string>Apply</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Close|QDialogButtonBox::Help</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ <action name="actionCopyAsCSV">
+ <property name="text">
+ <string>Copy as CSV</string>
+ </property>
+ <property name="toolTip">
+ <string>Copy the tree as CSV</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+C</string>
+ </property>
+ </action>
+ <action name="actionCopyAsYAML">
+ <property name="text">
+ <string>Copy as YAML</string>
+ </property>
+ <property name="toolTip">
+ <string>Copy the tree as YAML</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+Y</string>
+ </property>
+ </action>
+ <action name="action_SourceDataFrames">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>Data frames</string>
+ </property>
+ <property name="toolTip">
+ <string>Show the data frames column</string>
+ </property>
+ </action>
+ <action name="action_SourceDataBytes">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>Data bytes</string>
+ </property>
+ <property name="toolTip">
+ <string>Show the data bytes column</string>
+ </property>
+ </action>
+ <action name="action_SourceDataFramesBytes">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>Data frames/bytes</string>
+ </property>
+ <property name="toolTip">
+ <string>Show the data frames/bytes column</string>
+ </property>
+ </action>
+ <action name="action_SourceRXDataFrames">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>RX data frames</string>
+ </property>
+ <property name="toolTip">
+ <string>Show the RX data frames column</string>
+ </property>
+ </action>
+ <action name="action_SourceRXDataBytes">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>RX data bytes</string>
+ </property>
+ <property name="toolTip">
+ <string>Show the RX data bytes column</string>
+ </property>
+ </action>
+ <action name="action_SourceRXDataFramesBytes">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>RX data frames/bytes</string>
+ </property>
+ <property name="toolTip">
+ <string>Show the RX data frames/bytes column</string>
+ </property>
+ </action>
+ <action name="action_SourceNCFFrames">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>NCF frames</string>
+ </property>
+ <property name="toolTip">
+ <string>Show the NCF frames column</string>
+ </property>
+ </action>
+ <action name="action_SourceNCFBytes">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>NCF bytes</string>
+ </property>
+ <property name="toolTip">
+ <string>Show the NCF bytes column</string>
+ </property>
+ </action>
+ <action name="action_SourceNCFCount">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>NCF count</string>
+ </property>
+ <property name="toolTip">
+ <string>Show the NCF count column</string>
+ </property>
+ </action>
+ <action name="action_SourceDataRate">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>Data rate</string>
+ </property>
+ <property name="toolTip">
+ <string>Show the data rate column</string>
+ </property>
+ </action>
+ <action name="action_SourceRXDataRate">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>RX data rate</string>
+ </property>
+ <property name="toolTip">
+ <string>Show the RX data rate column</string>
+ </property>
+ </action>
+ <action name="action_SourceNCFFramesBytes">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>NCF frames/bytes</string>
+ </property>
+ <property name="toolTip">
+ <string>Show the NCF frames/bytes column</string>
+ </property>
+ </action>
+ <action name="action_SourceNCFCountBytes">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>NCF count/bytes</string>
+ </property>
+ <property name="toolTip">
+ <string>Show the NCF count/bytes column</string>
+ </property>
+ </action>
+ <action name="action_SourceNCFFramesCount">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>NCF frames/count</string>
+ </property>
+ <property name="toolTip">
+ <string>Show the NCF frames/count column</string>
+ </property>
+ </action>
+ <action name="action_SourceNCFFramesCountBytes">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>NCF frames/count/bytes</string>
+ </property>
+ <property name="toolTip">
+ <string>Show the NCF frames/count/bytes column</string>
+ </property>
+ </action>
+ <action name="action_SourceNCFRate">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>NCF rate</string>
+ </property>
+ <property name="toolTip">
+ <string>Show the NCF rate column</string>
+ </property>
+ </action>
+ <action name="action_SourceSMFrames">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>SM frames</string>
+ </property>
+ <property name="toolTip">
+ <string>Show the SM frames column</string>
+ </property>
+ </action>
+ <action name="action_SourceSMBytes">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>SM bytes</string>
+ </property>
+ <property name="toolTip">
+ <string>Show the SM bytes column</string>
+ </property>
+ </action>
+ <action name="action_SourceSMFramesBytes">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>SM frames/bytes</string>
+ </property>
+ <property name="toolTip">
+ <string>Show the SM frames/bytes column</string>
+ </property>
+ </action>
+ <action name="action_SourceSMRate">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>SM rate</string>
+ </property>
+ <property name="toolTip">
+ <string>Show the SM rate column</string>
+ </property>
+ </action>
+ <action name="action_SourceAutoResizeColumns">
+ <property name="text">
+ <string>Auto-resize columns to content</string>
+ </property>
+ <property name="toolTip">
+ <string>Resize columns to content size</string>
+ </property>
+ </action>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>DisplayFilterEdit</class>
+ <extends>QLineEdit</extends>
+ <header location="global">display_filter_edit.h</header>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>LBMLBTRMTransportDialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>255</x>
+ <y>555</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>157</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>LBMLBTRMTransportDialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>323</x>
+ <y>555</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>286</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>sources_detail_ComboBox</sender>
+ <signal>currentIndexChanged(int)</signal>
+ <receiver>LBMLBTRMTransportDialog</receiver>
+ <slot>sourcesDetailCurrentChanged(int)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>135</x>
+ <y>269</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>446</x>
+ <y>310</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>sources_TreeWidget</sender>
+ <signal>itemClicked(QTreeWidgetItem*,int)</signal>
+ <receiver>LBMLBTRMTransportDialog</receiver>
+ <slot>sourcesItemClicked(QTreeWidgetItem*,int)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>440</x>
+ <y>149</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>446</x>
+ <y>310</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>receivers_TreeWidget</sender>
+ <signal>itemClicked(QTreeWidgetItem*,int)</signal>
+ <receiver>LBMLBTRMTransportDialog</receiver>
+ <slot>receiversItemClicked(QTreeWidgetItem*,int)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>420</x>
+ <y>141</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>420</x>
+ <y>281</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>receivers_detail_TreeWidget</sender>
+ <signal>itemDoubleClicked(QTreeWidgetItem*,int)</signal>
+ <receiver>LBMLBTRMTransportDialog</receiver>
+ <slot>receiversDetailItemDoubleClicked(QTreeWidgetItem*,int)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>75</x>
+ <y>328</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>420</x>
+ <y>281</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>sources_detail_sqn_TreeWidget</sender>
+ <signal>itemDoubleClicked(QTreeWidgetItem*,int)</signal>
+ <receiver>LBMLBTRMTransportDialog</receiver>
+ <slot>sourcesDetailItemDoubleClicked(QTreeWidgetItem*,int)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>420</x>
+ <y>377</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>420</x>
+ <y>281</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>sources_detail_ncf_sqn_TreeWidget</sender>
+ <signal>itemDoubleClicked(QTreeWidgetItem*,int)</signal>
+ <receiver>LBMLBTRMTransportDialog</receiver>
+ <slot>sourcesDetailItemDoubleClicked(QTreeWidgetItem*,int)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>66</x>
+ <y>290</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>420</x>
+ <y>281</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+ <slots>
+ <signal>goToPacket(int)</signal>
+ <slot>sourcesDetailCurrentChanged(int)</slot>
+ <slot>sourcesItemClicked(QTreeWidgetItem*,int)</slot>
+ <slot>receiversItemClicked(QTreeWidgetItem*,int)</slot>
+ <slot>sourcesDetailItemDoubleClicked(QTreeWidgetItem*,int)</slot>
+ <slot>receiversDetailItemDoubleClicked(QTreeWidgetItem*,int)</slot>
+ </slots>
+</ui>
diff --git a/ui/qt/lbm_lbtru_transport_dialog.cpp b/ui/qt/lbm_lbtru_transport_dialog.cpp
new file mode 100644
index 0000000000..6ad608edb0
--- /dev/null
+++ b/ui/qt/lbm_lbtru_transport_dialog.cpp
@@ -0,0 +1,2251 @@
+/* lbm_lbtru_transport_dialog.cpp
+ *
+ * Copyright (c) 2005-2014 Informatica Corporation. All Rights Reserved.
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "lbm_lbtru_transport_dialog.h"
+#include "ui_lbm_lbtru_transport_dialog.h"
+
+#include "file.h"
+
+#include "wireshark_application.h"
+
+#include <QClipboard>
+#include <QMessageBox>
+#include <QTreeWidget>
+#include <QTreeWidgetItemIterator>
+#include <QMenu>
+#include <epan/packet_info.h>
+#include <epan/tap.h>
+#include <epan/to_str.h>
+#include <epan/wmem/wmem.h>
+#include <epan/dissectors/packet-lbm.h>
+#include <wsutil/nstime.h>
+
+#include <QDebug>
+
+namespace
+{
+ static const int Source_AddressTransport_Column = 0;
+ static const int Source_DataFrames_Column = 1;
+ static const int Source_DataBytes_Column = 2;
+ static const int Source_DataFramesBytes_Column = 3;
+ static const int Source_DataRate_Column = 4;
+ static const int Source_RXDataFrames_Column = 5;
+ static const int Source_RXDataBytes_Column = 6;
+ static const int Source_RXDataFramesBytes_Column = 7;
+ static const int Source_RXDataRate_Column = 8;
+ static const int Source_NCFFrames_Column = 9;
+ static const int Source_NCFCount_Column = 10;
+ static const int Source_NCFBytes_Column = 11;
+ static const int Source_NCFFramesBytes_Column = 12;
+ static const int Source_NCFCountBytes_Column = 13;
+ static const int Source_NCFFramesCount_Column = 14;
+ static const int Source_NCFFramesCountBytes_Column = 15;
+ static const int Source_NCFRate_Column = 16;
+ static const int Source_SMFrames_Column = 17;
+ static const int Source_SMBytes_Column = 18;
+ static const int Source_SMFramesBytes_Column = 19;
+ static const int Source_SMRate_Column = 20;
+ static const int Source_RSTFrames_Column = 21;
+ static const int Source_RSTBytes_Column = 22;
+ static const int Source_RSTFramesBytes_Column = 23;
+ static const int Source_RSTRate_Column = 24;
+
+ static const int Receiver_AddressTransport_Column = 0;
+ static const int Receiver_NAKFrames_Column = 1;
+ static const int Receiver_NAKCount_Column = 2;
+ static const int Receiver_NAKBytes_Column = 3;
+ static const int Receiver_NAKFramesCount_Column = 4;
+ static const int Receiver_NAKCountBytes_Column = 5;
+ static const int Receiver_NAKFramesBytes_Column = 6;
+ static const int Receiver_NAKFramesCountBytes_Column = 7;
+ static const int Receiver_NAKRate_Column = 8;
+ static const int Receiver_ACKFrames_Column = 9;
+ static const int Receiver_ACKBytes_Column = 10;
+ static const int Receiver_ACKFramesBytes_Column = 11;
+ static const int Receiver_ACKRate_Column = 12;
+ static const int Receiver_CREQFrames_Column = 13;
+ static const int Receiver_CREQBytes_Column = 14;
+ static const int Receiver_CREQFramesBytes_Column = 15;
+ static const int Receiver_CREQRate_Column = 16;
+
+ static const int Detail_SQNReasonType_Column = 0;
+ static const int Detail_Count_Column = 1;
+ static const int Detail_Frame_Column = 2;
+
+ static const double OneKilobit = 1000.0;
+ static const double OneMegabit = OneKilobit * OneKilobit;
+ static const double OneGigabit = OneMegabit * OneKilobit;
+}
+
+static QString format_rate(const nstime_t & elapsed, guint64 bytes)
+{
+ QString result;
+ double elapsed_sec;
+ double rate;
+
+ if (((elapsed.secs == 0) && (elapsed.nsecs == 0)) || (bytes == 0))
+ {
+ return (QString("0"));
+ }
+
+ elapsed_sec = elapsed.secs + (((double)elapsed.nsecs) / 1000000000.0);
+ rate = ((double)(bytes * 8)) / elapsed_sec;
+
+ // Currently rate is in bps
+ if (rate >= OneGigabit)
+ {
+ rate /= OneGigabit;
+ result = QString("%1G").arg(rate, 0, 'f', 2);
+ }
+ else if (rate >= OneMegabit)
+ {
+ rate /= OneMegabit;
+ result = QString("%1M").arg(rate, 0, 'f', 2);
+ }
+ else if (rate >= OneKilobit)
+ {
+ rate /= OneKilobit;
+ result = QString("%1K").arg(rate, 0, 'f', 2);
+ }
+ else
+ {
+ result = QString("%1").arg(rate, 0, 'f', 2);
+ }
+ return (result);
+}
+
+// Note:
+// LBMLBTRUFrameEntry, LBMLBTRUSQNEntry, LBMLBTRUNCFReasonEntry, LBMLBTRUNCFSQNEntry, LBMLBTRURSTReasonEntry, LBMLBTRUCREQRequestEntry,
+// LBMLBTRUSourceTransportEntry, LBMLBTRUSourceEntry, LBMLBTRUReceiverTransportEntry, and LBMLBTRUReceiverEntry are all derived from
+// a QTreeWidgetItem. Each instantiation can exist in two places: in a QTreeWidget, and in a containing QMap.
+//
+// For example:
+// - LBMLBTRUTransportDialogInfo contains a QMap of the sources (LBMLBTRUSourceEntry) and receivers (LBMLBTRUReceiverEntry)
+// - A source (LBMLBTRUSourceEntry) contains a QMap of the source transports originating from it (LBMLBTRUSourceTransportEntry)
+// - A source transport (LBMLBTRUSourceTransportEntry) contains QMaps of data, RX data, and SM SQNs (LBMLBTRUSQNEntry), NCF SQNs
+// (LBMLBTRUNCFSQNEntry), and RST reasons (LBMLBTRURSTReasonEntry)
+// - A data SQN (LBMLBTRUSQNEntry) contains a QMap of the frames (LBMLBTRUFrameEntry) in which that SQN appears
+//
+// Not all of the entries actually appear in a QTreeWidget at one time. For example, in the source details, if no specific source
+// transport is selected, nothing is in the source details tree. If Data SQNs is selected, then those details appear in the source
+// details tree. Switching to RX Data SQNs removes whatever is currently in the source details tree, and adds the RX details for
+// the selected transport.
+//
+// The actual owner of one of the above QTreeWidgetItem-derived items is the QMap container in its parent. The item is "loaned" to
+// the QTreeWidget for display.
+//
+// All of this is to explain why
+// 1) we are frequently adding things to a QTreeWidget
+// 2) things are removed (takeTopLevelItem) from a QTreeWidget
+// 3) destruction involves removing all items from all QTreeWidgets (rather than letting QTreeWidget delete them)
+// 4) the destructor for each item has the form
+// <for each QMap container>
+// for (XXXMapIterator it = m_xxx.begin(); it != m_xxx.end(); it++)
+// {
+// delete *it;
+// }
+// m_xxx.clear();
+// The for-loop calls the destructor for each item, while the clear() cleans up the space used by the QMap itself.
+
+// A frame entry
+class LBMLBTRUFrameEntry : public QTreeWidgetItem
+{
+ public:
+ LBMLBTRUFrameEntry(guint32 frame);
+ virtual ~LBMLBTRUFrameEntry(void) { }
+ guint32 getFrame(void) { return (m_frame); }
+
+ private:
+ LBMLBTRUFrameEntry(void) { }
+ guint32 m_frame;
+};
+
+LBMLBTRUFrameEntry::LBMLBTRUFrameEntry(guint32 frame) :
+ QTreeWidgetItem(),
+ m_frame(frame)
+{
+ setText(Detail_SQNReasonType_Column, QString(" "));
+ setText(Detail_Count_Column, QString(" "));
+ setText(Detail_Frame_Column, QString("%1").arg(m_frame));
+}
+
+typedef QMap<guint32, LBMLBTRUFrameEntry *> LBMLBTRUFrameMap;
+typedef QMap<guint32, LBMLBTRUFrameEntry *>::iterator LBMLBTRUFrameMapIterator;
+
+// An SQN (SeQuence Number) entry
+class LBMLBTRUSQNEntry : public QTreeWidgetItem
+{
+ public:
+ LBMLBTRUSQNEntry(guint32 sqn);
+ virtual ~LBMLBTRUSQNEntry(void);
+ void processFrame(guint32 frame);
+
+ private:
+ LBMLBTRUSQNEntry(void);
+ guint32 m_sqn;
+ guint32 m_count;
+ LBMLBTRUFrameMap m_frames;
+};
+
+LBMLBTRUSQNEntry::LBMLBTRUSQNEntry(guint32 sqn) :
+ QTreeWidgetItem(),
+ m_sqn(sqn),
+ m_count(0),
+ m_frames()
+{
+ setText(Detail_SQNReasonType_Column, QString("%1").arg(m_sqn));
+ setTextAlignment(Detail_SQNReasonType_Column, Qt::AlignRight);
+ setText(Detail_Count_Column, QString("%1").arg(m_count));
+ setTextAlignment(Detail_Count_Column, Qt::AlignRight);
+ setText(Detail_Frame_Column, QString(" "));
+}
+
+LBMLBTRUSQNEntry::~LBMLBTRUSQNEntry(void)
+{
+ for (LBMLBTRUFrameMapIterator it = m_frames.begin(); it != m_frames.end(); it++)
+ {
+ delete *it;
+ }
+ m_frames.clear();
+}
+
+void LBMLBTRUSQNEntry::processFrame(guint32 frame)
+{
+ LBMLBTRUFrameMapIterator it;
+
+ it = m_frames.find(frame);
+ if (m_frames.end() == it)
+ {
+ LBMLBTRUFrameEntry * entry = new LBMLBTRUFrameEntry(frame);
+ m_frames.insert(frame, entry);
+ addChild(entry);
+ sortChildren(Detail_Frame_Column, Qt::AscendingOrder);
+ }
+ m_count++;
+ setText(Detail_Count_Column, QString("%1").arg(m_count));
+ setTextAlignment(Detail_Count_Column, Qt::AlignRight);
+}
+
+// An NCF (Nak ConFirmation) Reason entry
+class LBMLBTRUNCFReasonEntry : public QTreeWidgetItem
+{
+ public:
+ LBMLBTRUNCFReasonEntry(guint8 reason);
+ virtual ~LBMLBTRUNCFReasonEntry(void);
+ void processFrame(guint32 frame);
+
+ private:
+ LBMLBTRUNCFReasonEntry(void);
+ guint8 m_reason;
+ guint32 m_count;
+ LBMLBTRUFrameMap m_frames;
+};
+
+LBMLBTRUNCFReasonEntry::LBMLBTRUNCFReasonEntry(guint8 reason) :
+ QTreeWidgetItem(),
+ m_reason(reason),
+ m_count(0),
+ m_frames()
+{
+ switch (m_reason)
+ {
+ case LBTRU_NCF_REASON_NO_RETRY:
+ setText(Detail_SQNReasonType_Column, QString("No Retry"));
+ break;
+ case LBTRU_NCF_REASON_IGNORED:
+ setText(Detail_SQNReasonType_Column, QString("Ignored"));
+ break;
+ case LBTRU_NCF_REASON_RX_DELAY:
+ setText(Detail_SQNReasonType_Column, QString("Retransmit Delay"));
+ break;
+ case LBTRU_NCF_REASON_SHED:
+ setText(Detail_SQNReasonType_Column, QString("Shed"));
+ break;
+ default:
+ setText(Detail_SQNReasonType_Column, QString("Unknown"));
+ break;
+ }
+ setText(Detail_Count_Column, QString("%1").arg(m_count));
+ setTextAlignment(Detail_Count_Column, Qt::AlignRight);
+ setText(Detail_Frame_Column, QString(" "));
+}
+
+LBMLBTRUNCFReasonEntry::~LBMLBTRUNCFReasonEntry(void)
+{
+ for (LBMLBTRUFrameMapIterator it = m_frames.begin(); it != m_frames.end(); it++)
+ {
+ delete *it;
+ }
+ m_frames.clear();
+}
+
+void LBMLBTRUNCFReasonEntry::processFrame(guint32 frame)
+{
+ LBMLBTRUFrameMapIterator it;
+
+ it = m_frames.find(frame);
+ if (m_frames.end() == it)
+ {
+ LBMLBTRUFrameEntry * entry = new LBMLBTRUFrameEntry(frame);
+ m_frames.insert(frame, entry);
+ addChild(entry);
+ sortChildren(Detail_Frame_Column, Qt::AscendingOrder);
+ }
+ m_count++;
+ setText(Detail_Count_Column, QString("%1").arg(m_count));
+ setTextAlignment(Detail_Count_Column, Qt::AlignRight);
+}
+
+typedef QMap<guint8, LBMLBTRUNCFReasonEntry *> LBMLBTRUNCFReasonMap;
+typedef QMap<guint8, LBMLBTRUNCFReasonEntry *>::iterator LBMLBTRUNCFReasonMapIterator;
+
+// An NCF SQN entry
+class LBMLBTRUNCFSQNEntry : public QTreeWidgetItem
+{
+ public:
+ LBMLBTRUNCFSQNEntry(guint32 sqn);
+ virtual ~LBMLBTRUNCFSQNEntry(void);
+ void processFrame(guint8 reason, guint32 frame);
+
+ private:
+ LBMLBTRUNCFSQNEntry(void);
+ guint32 m_sqn;
+ guint32 m_count;
+ LBMLBTRUNCFReasonMap m_reasons;
+};
+
+LBMLBTRUNCFSQNEntry::LBMLBTRUNCFSQNEntry(guint32 sqn) :
+ QTreeWidgetItem(),
+ m_sqn(sqn),
+ m_count(0),
+ m_reasons()
+{
+ setText(Detail_SQNReasonType_Column, QString("%1").arg(m_sqn));
+ setTextAlignment(Detail_SQNReasonType_Column, Qt::AlignRight);
+ setText(Detail_Count_Column, QString("%1").arg(m_count));
+ setTextAlignment(Detail_Count_Column, Qt::AlignRight);
+ setText(Detail_Frame_Column, QString(" "));
+}
+
+LBMLBTRUNCFSQNEntry::~LBMLBTRUNCFSQNEntry(void)
+{
+ for (LBMLBTRUNCFReasonMapIterator it = m_reasons.begin(); it != m_reasons.end(); it++)
+ {
+ delete *it;
+ }
+ m_reasons.clear();
+}
+
+void LBMLBTRUNCFSQNEntry::processFrame(guint8 reason, guint32 frame)
+{
+ LBMLBTRUNCFReasonMapIterator it;
+ LBMLBTRUNCFReasonEntry * entry = NULL;
+
+ it = m_reasons.find(reason);
+ if (m_reasons.end() == it)
+ {
+ entry = new LBMLBTRUNCFReasonEntry(reason);
+ m_reasons.insert(reason, entry);
+ addChild(entry);
+ sortChildren(Detail_Frame_Column, Qt::AscendingOrder);
+ }
+ else
+ {
+ entry = it.value();
+ }
+ m_count++;
+ setText(Detail_Count_Column, QString("%1").arg(m_count));
+ setTextAlignment(Detail_Count_Column, Qt::AlignRight);
+ entry->processFrame(frame);
+}
+
+// An RST (ReSeT) Reason entry
+class LBMLBTRURSTReasonEntry : public QTreeWidgetItem
+{
+ public:
+ LBMLBTRURSTReasonEntry(guint32 reason);
+ virtual ~LBMLBTRURSTReasonEntry(void);
+ void processFrame(guint32 frame);
+
+ private:
+ LBMLBTRURSTReasonEntry(void);
+ guint32 m_reason;
+ QString m_reason_string;
+ guint32 m_count;
+ LBMLBTRUFrameMap m_frames;
+};
+
+LBMLBTRURSTReasonEntry::LBMLBTRURSTReasonEntry(guint32 reason) :
+ QTreeWidgetItem(),
+ m_reason(reason),
+ m_reason_string(),
+ m_count(0),
+ m_frames()
+{
+ switch (m_reason)
+ {
+ case LBTRU_RST_REASON_DEFAULT:
+ m_reason_string = "Default";
+ break;
+ default:
+ m_reason_string = QString("Unknown (%1)").arg(m_reason);
+ break;
+ }
+ setText(Detail_SQNReasonType_Column, m_reason_string);
+ setTextAlignment(Detail_SQNReasonType_Column, Qt::AlignLeft);
+ setText(Detail_Count_Column, QString("%1").arg(m_count));
+ setTextAlignment(Detail_Count_Column, Qt::AlignRight);
+ setText(Detail_Frame_Column, QString(" "));
+}
+
+LBMLBTRURSTReasonEntry::~LBMLBTRURSTReasonEntry(void)
+{
+ for (LBMLBTRUFrameMapIterator it = m_frames.begin(); it != m_frames.end(); it++)
+ {
+ delete *it;
+ }
+ m_frames.clear();
+}
+
+void LBMLBTRURSTReasonEntry::processFrame(guint32 frame)
+{
+ LBMLBTRUFrameMapIterator it;
+
+ it = m_frames.find(frame);
+ if (m_frames.end() == it)
+ {
+ LBMLBTRUFrameEntry * entry = new LBMLBTRUFrameEntry(frame);
+ m_frames.insert(frame, entry);
+ addChild(entry);
+ sortChildren(Detail_Frame_Column, Qt::AscendingOrder);
+ }
+ m_count++;
+ setText(Detail_Count_Column, QString("%1").arg(m_count));
+ setTextAlignment(Detail_Count_Column, Qt::AlignRight);
+}
+
+// A CREQ (Connection REQuest) Request entry
+class LBMLBTRUCREQRequestEntry : public QTreeWidgetItem
+{
+ public:
+ LBMLBTRUCREQRequestEntry(guint32 request);
+ virtual ~LBMLBTRUCREQRequestEntry(void);
+ void processFrame(guint32 frame);
+
+ private:
+ LBMLBTRUCREQRequestEntry(void);
+ guint32 m_request;
+ QString m_request_string;
+ guint32 m_count;
+ LBMLBTRUFrameMap m_frames;
+};
+
+LBMLBTRUCREQRequestEntry::LBMLBTRUCREQRequestEntry(guint32 request) :
+ QTreeWidgetItem(),
+ m_request(request),
+ m_request_string(),
+ m_count(0),
+ m_frames()
+{
+ switch (m_request)
+ {
+ case LBTRU_CREQ_REQUEST_SYN:
+ m_request_string = "SYN";
+ break;
+ default:
+ m_request_string = QString("Unknown (%1)").arg(m_request);
+ break;
+ }
+ setText(Detail_SQNReasonType_Column, m_request_string);
+ setTextAlignment(Detail_SQNReasonType_Column, Qt::AlignLeft);
+ setText(Detail_Count_Column, QString("%1").arg(m_count));
+ setTextAlignment(Detail_Count_Column, Qt::AlignRight);
+ setText(Detail_Frame_Column, QString(" "));
+}
+
+LBMLBTRUCREQRequestEntry::~LBMLBTRUCREQRequestEntry(void)
+{
+ for (LBMLBTRUFrameMapIterator it = m_frames.begin(); it != m_frames.end(); it++)
+ {
+ delete *it;
+ }
+ m_frames.clear();
+}
+
+void LBMLBTRUCREQRequestEntry::processFrame(guint32 frame)
+{
+ LBMLBTRUFrameMapIterator it;
+
+ it = m_frames.find(frame);
+ if (m_frames.end() == it)
+ {
+ LBMLBTRUFrameEntry * entry = new LBMLBTRUFrameEntry(frame);
+ m_frames.insert(frame, entry);
+ addChild(entry);
+ sortChildren(Detail_Frame_Column, Qt::AscendingOrder);
+ }
+ m_count++;
+ setText(Detail_Count_Column, QString("%1").arg(m_count));
+ setTextAlignment(Detail_Count_Column, Qt::AlignRight);
+}
+
+typedef QMap<guint32, LBMLBTRUSQNEntry *> LBMLBTRUSQNMap;
+typedef QMap<guint32, LBMLBTRUSQNEntry *>::iterator LBMLBTRUSQNMapIterator;
+typedef QMap<guint32, LBMLBTRUNCFSQNEntry *> LBMLBTRUNCFSQNMap;
+typedef QMap<guint32, LBMLBTRUNCFSQNEntry *>::iterator LBMLBTRUNCFSQNMapIterator;
+typedef QMap<guint32, LBMLBTRURSTReasonEntry *> LBMLBTRURSTReasonMap;
+typedef QMap<guint32, LBMLBTRURSTReasonEntry *>::iterator LBMLBTRURSTReasonMapIterator;
+typedef QMap<guint32, LBMLBTRUCREQRequestEntry *> LBMLBTRUCREQRequestMap;
+typedef QMap<guint32, LBMLBTRUCREQRequestEntry *>::iterator LBMLBTRUCREQRequestMapIterator;
+
+// A source transport entry
+class LBMLBTRUSourceTransportEntry : public QTreeWidgetItem
+{
+ friend class LBMLBTRUTransportDialog;
+
+ public:
+ LBMLBTRUSourceTransportEntry(const QString & transport);
+ virtual ~LBMLBTRUSourceTransportEntry(void);
+ void processPacket(const packet_info * pinfo, const lbm_lbtru_tap_info_t * tap_info);
+
+ protected:
+ QString m_transport;
+
+ private:
+ LBMLBTRUSourceTransportEntry(void) { }
+ void fillItem(void);
+ guint64 m_data_frames;
+ guint64 m_data_bytes;
+ guint64 m_rx_data_frames;
+ guint64 m_rx_data_bytes;
+ guint64 m_ncf_frames;
+ guint64 m_ncf_count;
+ guint64 m_ncf_bytes;
+ guint64 m_sm_frames;
+ guint64 m_sm_bytes;
+ guint64 m_rst_frames;
+ guint64 m_rst_bytes;
+ nstime_t m_first_frame_timestamp;
+ bool m_first_frame_timestamp_valid;
+ nstime_t m_last_frame_timestamp;
+
+ protected:
+ LBMLBTRUSQNMap m_data_sqns;
+ LBMLBTRUSQNMap m_rx_data_sqns;
+ LBMLBTRUNCFSQNMap m_ncf_sqns;
+ LBMLBTRUSQNMap m_sm_sqns;
+ LBMLBTRURSTReasonMap m_rst_reasons;
+};
+
+LBMLBTRUSourceTransportEntry::LBMLBTRUSourceTransportEntry(const QString & transport) :
+ QTreeWidgetItem(),
+ m_transport(transport),
+ m_data_frames(0),
+ m_data_bytes(0),
+ m_rx_data_frames(0),
+ m_rx_data_bytes(0),
+ m_ncf_frames(0),
+ m_ncf_count(0),
+ m_ncf_bytes(0),
+ m_sm_frames(0),
+ m_sm_bytes(0),
+ m_rst_frames(0),
+ m_rst_bytes(0),
+ m_first_frame_timestamp_valid(false),
+ m_data_sqns(),
+ m_rx_data_sqns(),
+ m_ncf_sqns(),
+ m_sm_sqns(),
+ m_rst_reasons()
+{
+ m_first_frame_timestamp.secs = 0;
+ m_first_frame_timestamp.nsecs = 0;
+ m_last_frame_timestamp.secs = 0;
+ m_last_frame_timestamp.nsecs = 0;
+ setText(Source_AddressTransport_Column, m_transport);
+}
+
+LBMLBTRUSourceTransportEntry::~LBMLBTRUSourceTransportEntry(void)
+{
+ for (LBMLBTRUSQNMapIterator it = m_data_sqns.begin(); it != m_data_sqns.end(); it++)
+ {
+ delete *it;
+ }
+ m_data_sqns.clear();
+
+ for (LBMLBTRUSQNMapIterator it = m_rx_data_sqns.begin(); it != m_rx_data_sqns.end(); it++)
+ {
+ delete *it;
+ }
+ m_rx_data_sqns.clear();
+
+ for (LBMLBTRUNCFSQNMapIterator it = m_ncf_sqns.begin(); it != m_ncf_sqns.end(); it++)
+ {
+ delete *it;
+ }
+ m_ncf_sqns.clear();
+
+ for (LBMLBTRUSQNMapIterator it = m_sm_sqns.begin(); it != m_sm_sqns.end(); it++)
+ {
+ delete *it;
+ }
+ m_sm_sqns.clear();
+
+ for (LBMLBTRURSTReasonMapIterator it = m_rst_reasons.begin(); it != m_rst_reasons.end(); it++)
+ {
+ delete *it;
+ }
+ m_rst_reasons.clear();
+}
+
+void LBMLBTRUSourceTransportEntry::processPacket(const packet_info * pinfo, const lbm_lbtru_tap_info_t * tap_info)
+{
+ if (m_first_frame_timestamp_valid)
+ {
+ if (nstime_cmp(&(pinfo->fd->abs_ts), &m_first_frame_timestamp) < 0)
+ {
+ nstime_copy(&(m_first_frame_timestamp), &(pinfo->fd->abs_ts));
+ }
+ }
+ else
+ {
+ nstime_copy(&(m_first_frame_timestamp), &(pinfo->fd->abs_ts));
+ m_first_frame_timestamp_valid = true;
+ }
+ if (nstime_cmp(&(pinfo->fd->abs_ts), &m_last_frame_timestamp) > 0)
+ {
+ nstime_copy(&(m_last_frame_timestamp), &(pinfo->fd->abs_ts));
+ }
+ if (tap_info->type == LBTRU_PACKET_TYPE_DATA)
+ {
+ LBMLBTRUSQNEntry * sqn = NULL;
+ LBMLBTRUSQNMapIterator it;
+
+ if (tap_info->retransmission)
+ {
+ m_rx_data_frames++;
+ m_rx_data_bytes += pinfo->fd->pkt_len;
+ it = m_rx_data_sqns.find(tap_info->sqn);
+ if (m_rx_data_sqns.end() == it)
+ {
+ sqn = new LBMLBTRUSQNEntry(tap_info->sqn);
+ m_rx_data_sqns.insert(tap_info->sqn, sqn);
+ }
+ else
+ {
+ sqn = it.value();
+ }
+ sqn->processFrame(pinfo->fd->num);
+ }
+ else
+ {
+ m_data_frames++;
+ m_data_bytes += pinfo->fd->pkt_len;
+ it = m_data_sqns.find(tap_info->sqn);
+ if (m_data_sqns.end() == it)
+ {
+ sqn = new LBMLBTRUSQNEntry(tap_info->sqn);
+ m_data_sqns.insert(tap_info->sqn, sqn);
+ }
+ else
+ {
+ sqn = it.value();
+ }
+ }
+ sqn->processFrame(pinfo->fd->num);
+ }
+ else if (tap_info->type == LBTRU_PACKET_TYPE_NCF)
+ {
+ guint16 idx;
+ LBMLBTRUNCFSQNMapIterator it;
+ LBMLBTRUNCFSQNEntry * sqn = NULL;
+
+ m_ncf_frames++;
+ m_ncf_bytes += pinfo->fd->pkt_len;
+ m_ncf_count += (guint64)tap_info->num_sqns;
+ for (idx = 0; idx < tap_info->num_sqns; idx++)
+ {
+ it = m_ncf_sqns.find(tap_info->sqns[idx]);
+ if (m_ncf_sqns.end() == it)
+ {
+ sqn = new LBMLBTRUNCFSQNEntry(tap_info->sqns[idx]);
+ m_ncf_sqns.insert(tap_info->sqns[idx], sqn);
+ }
+ else
+ {
+ sqn = it.value();
+ }
+ sqn->processFrame(tap_info->ncf_reason, pinfo->fd->num);
+ }
+ }
+ else if (tap_info->type == LBTRU_PACKET_TYPE_SM)
+ {
+ LBMLBTRUSQNEntry * sqn = NULL;
+ LBMLBTRUSQNMapIterator it;
+
+ m_sm_frames++;
+ m_sm_bytes += pinfo->fd->pkt_len;
+ it = m_sm_sqns.find(tap_info->sqn);
+ if (m_sm_sqns.end() == it)
+ {
+ sqn = new LBMLBTRUSQNEntry(tap_info->sqn);
+ m_sm_sqns.insert(tap_info->sqn, sqn);
+ }
+ else
+ {
+ sqn = it.value();
+ }
+ sqn->processFrame(pinfo->fd->num);
+ }
+ else if (tap_info->type == LBTRU_PACKET_TYPE_RST)
+ {
+ LBMLBTRURSTReasonEntry * reason = NULL;
+ LBMLBTRURSTReasonMapIterator it;
+
+ m_rst_frames++;
+ m_rst_bytes += pinfo->fd->pkt_len;
+ it = m_rst_reasons.find(tap_info->rst_type);
+ if (m_rst_reasons.end() == it)
+ {
+ reason = new LBMLBTRURSTReasonEntry(tap_info->rst_type);
+ m_rst_reasons.insert((unsigned int) tap_info->rst_type, reason);
+ }
+ else
+ {
+ reason = it.value();
+ }
+ reason->processFrame(pinfo->fd->num);
+ }
+ else
+ {
+ return;
+ }
+ fillItem();
+}
+
+void LBMLBTRUSourceTransportEntry::fillItem(void)
+{
+ nstime_t delta;
+
+ nstime_delta(&delta, &m_last_frame_timestamp, &m_first_frame_timestamp);
+ setText(Source_DataFrames_Column, QString("%1").arg(m_data_frames));
+ setTextAlignment(Source_DataFrames_Column, Qt::AlignRight);
+ setText(Source_DataBytes_Column, QString("%1").arg(m_data_bytes));
+ setTextAlignment(Source_DataBytes_Column, Qt::AlignRight);
+ setText(Source_DataFramesBytes_Column, QString("%1/%2").arg(m_data_frames).arg(m_data_bytes));
+ setTextAlignment(Source_DataFramesBytes_Column, Qt::AlignHCenter);
+ setText(Source_DataRate_Column, format_rate(delta, m_data_bytes));
+ setTextAlignment(Source_DataRate_Column, Qt::AlignRight);
+ setText(Source_RXDataFrames_Column, QString("%1").arg(m_rx_data_frames));
+ setTextAlignment(Source_RXDataFrames_Column, Qt::AlignRight);
+ setText(Source_RXDataBytes_Column, QString("%1").arg(m_rx_data_bytes));
+ setTextAlignment(Source_RXDataBytes_Column, Qt::AlignRight);
+ setText(Source_RXDataFramesBytes_Column, QString("%1/%2").arg(m_rx_data_frames).arg(m_rx_data_bytes));
+ setTextAlignment(Source_RXDataFramesBytes_Column, Qt::AlignHCenter);
+ setText(Source_RXDataRate_Column, format_rate(delta, m_rx_data_bytes));
+ setTextAlignment(Source_RXDataRate_Column, Qt::AlignRight);
+ setText(Source_NCFFrames_Column, QString("%1").arg(m_ncf_frames));
+ setTextAlignment(Source_NCFFrames_Column, Qt::AlignRight);
+ setText(Source_NCFCount_Column, QString("%1").arg(m_ncf_count));
+ setTextAlignment(Source_NCFCount_Column, Qt::AlignRight);
+ setText(Source_NCFBytes_Column, QString("%1").arg(m_ncf_bytes));
+ setTextAlignment(Source_NCFBytes_Column, Qt::AlignRight);
+ setText(Source_NCFFramesBytes_Column, QString("%1/%2").arg(m_ncf_frames).arg(m_ncf_bytes));
+ setTextAlignment(Source_NCFFramesBytes_Column, Qt::AlignHCenter);
+ setText(Source_NCFCountBytes_Column, QString("%1/%2").arg(m_ncf_count).arg(m_ncf_bytes));
+ setTextAlignment(Source_NCFCountBytes_Column, Qt::AlignHCenter);
+ setText(Source_NCFFramesCount_Column, QString("%1/%2").arg(m_ncf_count).arg(m_ncf_count));
+ setTextAlignment(Source_NCFFramesCount_Column, Qt::AlignHCenter);
+ setText(Source_NCFFramesCountBytes_Column, QString("%1/%2/%3").arg(m_ncf_frames).arg(m_ncf_count).arg(m_ncf_bytes));
+ setTextAlignment(Source_NCFFramesCountBytes_Column, Qt::AlignHCenter);
+ setText(Source_NCFRate_Column, format_rate(delta, m_ncf_bytes));
+ setTextAlignment(Source_NCFRate_Column, Qt::AlignRight);
+ setText(Source_SMFrames_Column, QString("%1").arg(m_sm_frames));
+ setTextAlignment(Source_SMFrames_Column, Qt::AlignRight);
+ setText(Source_SMBytes_Column, QString("%1").arg(m_sm_bytes));
+ setTextAlignment(Source_SMBytes_Column, Qt::AlignRight);
+ setText(Source_SMFramesBytes_Column, QString("%1/%2").arg(m_sm_frames).arg(m_sm_bytes));
+ setTextAlignment(Source_SMFramesBytes_Column, Qt::AlignHCenter);
+ setText(Source_SMRate_Column, format_rate(delta, m_sm_bytes));
+ setTextAlignment(Source_SMRate_Column, Qt::AlignRight);
+ setText(Source_RSTFrames_Column, QString("%1").arg(m_rst_frames));
+ setTextAlignment(Source_RSTFrames_Column, Qt::AlignRight);
+ setText(Source_RSTBytes_Column, QString("%1").arg(m_rst_bytes));
+ setTextAlignment(Source_RSTBytes_Column, Qt::AlignRight);
+ setText(Source_RSTFramesBytes_Column, QString("%1/%2").arg(m_rst_frames).arg(m_rst_bytes));
+ setTextAlignment(Source_RSTFramesBytes_Column, Qt::AlignHCenter);
+ setText(Source_RSTRate_Column, format_rate(delta, m_rst_bytes));
+ setTextAlignment(Source_RSTRate_Column, Qt::AlignRight);
+}
+
+typedef QMap<QString, LBMLBTRUSourceTransportEntry *> LBMLBTRUSourceTransportMap;
+typedef QMap<QString, LBMLBTRUSourceTransportEntry *>::iterator LBMLBTRUSourceTransportMapIterator;
+
+// A source (address) entry
+class LBMLBTRUSourceEntry : public QTreeWidgetItem
+{
+ public:
+ LBMLBTRUSourceEntry(const QString & source_address);
+ virtual ~LBMLBTRUSourceEntry(void);
+ void processPacket(const packet_info * pinfo, const lbm_lbtru_tap_info_t * tap_info);
+
+ private:
+ LBMLBTRUSourceEntry(void) { }
+ void fillItem(void);
+ QString m_address;
+ QString m_transport;
+ guint64 m_data_frames;
+ guint64 m_data_bytes;
+ guint64 m_rx_data_frames;
+ guint64 m_rx_data_bytes;
+ guint64 m_ncf_frames;
+ guint64 m_ncf_count;
+ guint64 m_ncf_bytes;
+ guint64 m_sm_frames;
+ guint64 m_sm_bytes;
+ guint64 m_rst_frames;
+ guint64 m_rst_bytes;
+ nstime_t m_first_frame_timestamp;
+ bool m_first_frame_timestamp_valid;
+ nstime_t m_last_frame_timestamp;
+ LBMLBTRUSourceTransportMap m_transports;
+};
+
+LBMLBTRUSourceEntry::LBMLBTRUSourceEntry(const QString & source_address) :
+ QTreeWidgetItem(),
+ m_address(source_address),
+ m_data_frames(0),
+ m_data_bytes(0),
+ m_rx_data_frames(0),
+ m_rx_data_bytes(0),
+ m_ncf_frames(0),
+ m_ncf_count(0),
+ m_ncf_bytes(0),
+ m_sm_frames(0),
+ m_sm_bytes(0),
+ m_rst_frames(0),
+ m_rst_bytes(0),
+ m_first_frame_timestamp_valid(false),
+ m_transports()
+{
+ m_first_frame_timestamp.secs = 0;
+ m_first_frame_timestamp.nsecs = 0;
+ m_last_frame_timestamp.secs = 0;
+ m_last_frame_timestamp.nsecs = 0;
+ setText(Source_AddressTransport_Column, m_address);
+}
+
+LBMLBTRUSourceEntry::~LBMLBTRUSourceEntry(void)
+{
+ for (LBMLBTRUSourceTransportMapIterator it = m_transports.begin(); it != m_transports.end(); it++)
+ {
+ delete *it;
+ }
+ m_transports.clear();
+}
+
+void LBMLBTRUSourceEntry::processPacket(const packet_info * pinfo, const lbm_lbtru_tap_info_t * tap_info)
+{
+ LBMLBTRUSourceTransportEntry * transport = NULL;
+ LBMLBTRUSourceTransportMapIterator it;
+
+ if (m_first_frame_timestamp_valid)
+ {
+ if (nstime_cmp(&(pinfo->fd->abs_ts), &m_first_frame_timestamp) < 0)
+ {
+ nstime_copy(&(m_first_frame_timestamp), &(pinfo->fd->abs_ts));
+ }
+ }
+ else
+ {
+ nstime_copy(&(m_first_frame_timestamp), &(pinfo->fd->abs_ts));
+ m_first_frame_timestamp_valid = true;
+ }
+ if (nstime_cmp(&(pinfo->fd->abs_ts), &m_last_frame_timestamp) > 0)
+ {
+ nstime_copy(&(m_last_frame_timestamp), &(pinfo->fd->abs_ts));
+ }
+ switch (tap_info->type)
+ {
+ case LBTRU_PACKET_TYPE_DATA:
+ if (tap_info->retransmission)
+ {
+ m_rx_data_frames++;
+ m_rx_data_bytes += pinfo->fd->pkt_len;
+ }
+ else
+ {
+ m_data_frames++;
+ m_data_bytes += pinfo->fd->pkt_len;
+ }
+ break;
+ case LBTRU_PACKET_TYPE_NCF:
+ m_ncf_frames++;
+ m_ncf_bytes += pinfo->fd->pkt_len;
+ m_ncf_count += tap_info->num_sqns;
+ break;
+ case LBTRU_PACKET_TYPE_SM:
+ m_sm_frames++;
+ m_sm_bytes += pinfo->fd->pkt_len;
+ break;
+ case LBTRU_PACKET_TYPE_RST:
+ m_rst_frames++;
+ m_rst_bytes += pinfo->fd->pkt_len;
+ break;
+ }
+
+ it = m_transports.find(tap_info->transport);
+ if (m_transports.end() == it)
+ {
+ transport = new LBMLBTRUSourceTransportEntry(tap_info->transport);
+ m_transports.insert(tap_info->transport, transport);
+ addChild(transport);
+ sortChildren(Source_AddressTransport_Column, Qt::AscendingOrder);
+ }
+ else
+ {
+ transport = it.value();
+ }
+ fillItem();
+ transport->processPacket(pinfo, tap_info);
+}
+
+void LBMLBTRUSourceEntry::fillItem(void)
+{
+ nstime_t delta;
+
+ nstime_delta(&delta, &m_last_frame_timestamp, &m_first_frame_timestamp);
+ setText(Source_DataFrames_Column, QString("%1").arg(m_data_frames));
+ setTextAlignment(Source_DataFrames_Column, Qt::AlignRight);
+ setText(Source_DataBytes_Column, QString("%1").arg(m_data_bytes));
+ setTextAlignment(Source_DataBytes_Column, Qt::AlignRight);
+ setText(Source_DataFramesBytes_Column, QString("%1/%2").arg(m_data_frames).arg(m_data_bytes));
+ setTextAlignment(Source_DataFramesBytes_Column, Qt::AlignHCenter);
+ setText(Source_DataRate_Column, format_rate(delta, m_data_bytes));
+ setTextAlignment(Source_DataRate_Column, Qt::AlignRight);
+ setText(Source_RXDataFrames_Column, QString("%1").arg(m_rx_data_frames));
+ setTextAlignment(Source_RXDataFrames_Column, Qt::AlignRight);
+ setText(Source_RXDataBytes_Column, QString("%1").arg(m_rx_data_bytes));
+ setTextAlignment(Source_RXDataBytes_Column, Qt::AlignRight);
+ setText(Source_RXDataFramesBytes_Column, QString("%1/%2").arg(m_rx_data_frames).arg(m_rx_data_bytes));
+ setTextAlignment(Source_RXDataFramesBytes_Column, Qt::AlignHCenter);
+ setText(Source_RXDataRate_Column, format_rate(delta, m_rx_data_bytes));
+ setTextAlignment(Source_RXDataRate_Column, Qt::AlignRight);
+ setText(Source_NCFFrames_Column, QString("%1").arg(m_ncf_frames));
+ setTextAlignment(Source_NCFFrames_Column, Qt::AlignRight);
+ setText(Source_NCFCount_Column, QString("%1").arg(m_ncf_count));
+ setTextAlignment(Source_NCFCount_Column, Qt::AlignRight);
+ setText(Source_NCFBytes_Column, QString("%1").arg(m_ncf_bytes));
+ setTextAlignment(Source_NCFBytes_Column, Qt::AlignRight);
+ setText(Source_NCFFramesBytes_Column, QString("%1/%2").arg(m_ncf_frames).arg(m_ncf_bytes));
+ setTextAlignment(Source_NCFFramesBytes_Column, Qt::AlignHCenter);
+ setText(Source_NCFCountBytes_Column, QString("%1/%2").arg(m_ncf_count).arg(m_ncf_bytes));
+ setTextAlignment(Source_NCFCountBytes_Column, Qt::AlignHCenter);
+ setText(Source_NCFFramesCount_Column, QString("%1/%2").arg(m_ncf_frames).arg(m_ncf_count));
+ setTextAlignment(Source_NCFFramesCount_Column, Qt::AlignHCenter);
+ setText(Source_NCFFramesCountBytes_Column, QString("%1/%2/%3").arg(m_ncf_frames).arg(m_ncf_count).arg(m_ncf_bytes));
+ setTextAlignment(Source_NCFFramesCountBytes_Column, Qt::AlignHCenter);
+ setText(Source_NCFRate_Column, format_rate(delta, m_ncf_bytes));
+ setTextAlignment(Source_NCFRate_Column, Qt::AlignRight);
+ setText(Source_SMFrames_Column, QString("%1").arg(m_sm_frames));
+ setTextAlignment(Source_SMFrames_Column, Qt::AlignRight);
+ setText(Source_SMBytes_Column, QString("%1").arg(m_sm_bytes));
+ setTextAlignment(Source_SMBytes_Column, Qt::AlignRight);
+ setText(Source_SMFramesBytes_Column, QString("%1/%2").arg(m_sm_frames).arg(m_sm_bytes));
+ setTextAlignment(Source_SMFramesBytes_Column, Qt::AlignRight);
+ setText(Source_SMRate_Column, format_rate(delta, m_sm_bytes));
+ setTextAlignment(Source_SMRate_Column, Qt::AlignRight);
+ setText(Source_RSTFrames_Column, QString("%1").arg(m_rst_frames));
+ setTextAlignment(Source_RSTFrames_Column, Qt::AlignRight);
+ setText(Source_RSTBytes_Column, QString("%1").arg(m_rst_bytes));
+ setTextAlignment(Source_RSTBytes_Column, Qt::AlignRight);
+ setText(Source_RSTFramesBytes_Column, QString("%1/%2").arg(m_rst_frames).arg(m_rst_bytes));
+ setTextAlignment(Source_RSTFramesBytes_Column, Qt::AlignHCenter);
+ setText(Source_RSTRate_Column, format_rate(delta, m_rst_bytes));
+ setTextAlignment(Source_RSTRate_Column, Qt::AlignRight);
+}
+
+typedef QMap<QString, LBMLBTRUSourceEntry *> LBMLBTRUSourceMap;
+typedef QMap<QString, LBMLBTRUSourceEntry *>::iterator LBMLBTRUSourceMapIterator;
+
+// A receiver transport entry
+class LBMLBTRUReceiverTransportEntry : public QTreeWidgetItem
+{
+ friend class LBMLBTRUTransportDialog;
+
+ public:
+ LBMLBTRUReceiverTransportEntry(const QString & transport);
+ virtual ~LBMLBTRUReceiverTransportEntry(void);
+ void processPacket(const packet_info * pinfo, const lbm_lbtru_tap_info_t * tap_info);
+
+ private:
+ LBMLBTRUReceiverTransportEntry(void) { }
+ void fillItem(void);
+ QString m_transport;
+ guint64 m_nak_frames;
+ guint64 m_nak_count;
+ guint64 m_nak_bytes;
+ guint64 m_ack_frames;
+ guint64 m_ack_bytes;
+ guint64 m_creq_frames;
+ guint64 m_creq_bytes;
+ nstime_t m_first_frame_timestamp;
+ bool m_first_frame_timestamp_valid;
+ nstime_t m_last_frame_timestamp;
+
+ protected:
+ LBMLBTRUSQNMap m_nak_sqns;
+ LBMLBTRUSQNMap m_ack_sqns;
+ LBMLBTRUCREQRequestMap m_creq_requests;
+};
+
+LBMLBTRUReceiverTransportEntry::LBMLBTRUReceiverTransportEntry(const QString & transport) :
+ QTreeWidgetItem(),
+ m_transport(transport),
+ m_nak_frames(0),
+ m_nak_count(0),
+ m_nak_bytes(0),
+ m_ack_frames(0),
+ m_ack_bytes(0),
+ m_creq_frames(0),
+ m_creq_bytes(0),
+ m_first_frame_timestamp_valid(false),
+ m_nak_sqns(),
+ m_ack_sqns(),
+ m_creq_requests()
+{
+ m_first_frame_timestamp.secs = 0;
+ m_first_frame_timestamp.nsecs = 0;
+ m_last_frame_timestamp.secs = 0;
+ m_last_frame_timestamp.nsecs = 0;
+ setText(Receiver_AddressTransport_Column, m_transport);
+}
+
+LBMLBTRUReceiverTransportEntry::~LBMLBTRUReceiverTransportEntry(void)
+{
+ for (LBMLBTRUSQNMapIterator it = m_nak_sqns.begin(); it != m_nak_sqns.end(); it++)
+ {
+ delete *it;
+ }
+ m_nak_sqns.clear();
+
+ for (LBMLBTRUSQNMapIterator it = m_ack_sqns.begin(); it != m_ack_sqns.end(); it++)
+ {
+ delete *it;
+ }
+ m_ack_sqns.clear();
+
+ for (LBMLBTRUCREQRequestMapIterator it = m_creq_requests.begin(); it != m_creq_requests.end(); it++)
+ {
+ delete *it;
+ }
+ m_creq_requests.clear();
+}
+
+void LBMLBTRUReceiverTransportEntry::processPacket(const packet_info * pinfo, const lbm_lbtru_tap_info_t * tap_info)
+{
+ if (m_first_frame_timestamp_valid)
+ {
+ if (nstime_cmp(&(pinfo->fd->abs_ts), &m_first_frame_timestamp) < 0)
+ {
+ nstime_copy(&(m_first_frame_timestamp), &(pinfo->fd->abs_ts));
+ }
+ }
+ else
+ {
+ nstime_copy(&(m_first_frame_timestamp), &(pinfo->fd->abs_ts));
+ m_first_frame_timestamp_valid = true;
+ }
+ if (nstime_cmp(&(pinfo->fd->abs_ts), &m_last_frame_timestamp) > 0)
+ {
+ nstime_copy(&(m_last_frame_timestamp), &(pinfo->fd->abs_ts));
+ }
+ switch (tap_info->type)
+ {
+ case LBTRU_PACKET_TYPE_NAK:
+ {
+ guint16 idx;
+ LBMLBTRUSQNEntry * sqn = NULL;
+ LBMLBTRUSQNMapIterator it;
+
+ m_nak_frames++;
+ m_nak_bytes += pinfo->fd->pkt_len;
+ m_nak_count += tap_info->num_sqns;
+ for (idx = 0; idx < tap_info->num_sqns; idx++)
+ {
+ it = m_nak_sqns.find(tap_info->sqns[idx]);
+ if (m_nak_sqns.end() == it)
+ {
+ sqn = new LBMLBTRUSQNEntry(tap_info->sqns[idx]);
+ m_nak_sqns.insert(tap_info->sqns[idx], sqn);
+ }
+ else
+ {
+ sqn = it.value();
+ }
+ sqn->processFrame(pinfo->fd->num);
+ }
+ }
+ break;
+ case LBTRU_PACKET_TYPE_ACK:
+ {
+ LBMLBTRUSQNEntry * sqn = NULL;
+ LBMLBTRUSQNMapIterator it;
+
+ m_ack_frames++;
+ m_ack_bytes += pinfo->fd->pkt_len;
+ it = m_ack_sqns.find(tap_info->sqn);
+ if (m_ack_sqns.end() == it)
+ {
+ sqn = new LBMLBTRUSQNEntry(tap_info->sqn);
+ m_ack_sqns.insert(tap_info->sqn, sqn);
+ }
+ else
+ {
+ sqn = it.value();
+ }
+ sqn->processFrame(pinfo->fd->num);
+ }
+ break;
+ case LBTRU_PACKET_TYPE_CREQ:
+ {
+ LBMLBTRUCREQRequestEntry * req = NULL;
+ LBMLBTRUCREQRequestMapIterator it;
+
+ m_creq_frames++;
+ m_creq_bytes += pinfo->fd->pkt_len;
+ it = m_creq_requests.find(tap_info->creq_type);
+ if (m_creq_requests.end() == it)
+ {
+ req = new LBMLBTRUCREQRequestEntry(tap_info->creq_type);
+ m_creq_requests.insert(tap_info->creq_type, req);
+ }
+ else
+ {
+ req = it.value();
+ }
+ req->processFrame(pinfo->fd->num);
+ }
+ break;
+ default:
+ return;
+ break;
+ }
+ fillItem();
+}
+
+void LBMLBTRUReceiverTransportEntry::fillItem(void)
+{
+ nstime_t delta;
+
+ nstime_delta(&delta, &m_last_frame_timestamp, &m_first_frame_timestamp);
+ setText(Receiver_NAKFrames_Column, QString("%1").arg(m_nak_frames));
+ setTextAlignment(Receiver_NAKFrames_Column, Qt::AlignRight);
+ setText(Receiver_NAKCount_Column, QString("%1").arg(m_nak_count));
+ setTextAlignment(Receiver_NAKCount_Column, Qt::AlignRight);
+ setText(Receiver_NAKBytes_Column, QString("%1").arg(m_nak_bytes));
+ setTextAlignment(Receiver_NAKBytes_Column, Qt::AlignRight);
+ setText(Receiver_NAKFramesCount_Column, QString("%1/%2").arg(m_nak_frames).arg(m_nak_count));
+ setTextAlignment(Receiver_NAKFramesCount_Column, Qt::AlignHCenter);
+ setText(Receiver_NAKCountBytes_Column, QString("%1/%2").arg(m_nak_count).arg(m_nak_bytes));
+ setTextAlignment(Receiver_NAKCountBytes_Column, Qt::AlignHCenter);
+ setText(Receiver_NAKFramesBytes_Column, QString("%1/%2").arg(m_nak_frames).arg(m_nak_bytes));
+ setTextAlignment(Receiver_NAKFramesBytes_Column, Qt::AlignHCenter);
+ setText(Receiver_NAKFramesCountBytes_Column, QString("%1/%2/%3").arg(m_nak_frames).arg(m_nak_count).arg(m_nak_bytes));
+ setTextAlignment(Receiver_NAKFramesCountBytes_Column, Qt::AlignHCenter);
+ setText(Receiver_NAKRate_Column, format_rate(delta, m_nak_bytes));
+ setTextAlignment(Receiver_NAKRate_Column, Qt::AlignRight);
+ setText(Receiver_ACKFrames_Column, QString("%1").arg(m_ack_frames));
+ setTextAlignment(Receiver_ACKFrames_Column, Qt::AlignRight);
+ setText(Receiver_ACKBytes_Column, QString("%1").arg(m_ack_bytes));
+ setTextAlignment(Receiver_ACKBytes_Column, Qt::AlignRight);
+ setText(Receiver_ACKFramesBytes_Column, QString("%1/%2").arg(m_ack_frames).arg(m_ack_bytes));
+ setTextAlignment(Receiver_ACKFramesBytes_Column, Qt::AlignHCenter);
+ setText(Receiver_ACKRate_Column, format_rate(delta, m_ack_bytes));
+ setTextAlignment(Receiver_ACKRate_Column, Qt::AlignRight);
+ setText(Receiver_CREQFrames_Column, QString("%1").arg(m_creq_frames));
+ setTextAlignment(Receiver_CREQFrames_Column, Qt::AlignRight);
+ setText(Receiver_CREQBytes_Column, QString("%1").arg(m_creq_bytes));
+ setTextAlignment(Receiver_CREQBytes_Column, Qt::AlignRight);
+ setText(Receiver_CREQFramesBytes_Column, QString("%1/%2").arg(m_creq_frames).arg(m_creq_bytes));
+ setTextAlignment(Receiver_CREQFramesBytes_Column, Qt::AlignHCenter);
+ setText(Receiver_CREQRate_Column, format_rate(delta, m_creq_bytes));
+ setTextAlignment(Receiver_CREQRate_Column, Qt::AlignRight);
+}
+
+typedef QMap<QString, LBMLBTRUReceiverTransportEntry *> LBMLBTRUReceiverTransportMap;
+typedef QMap<QString, LBMLBTRUReceiverTransportEntry *>::iterator LBMLBTRUReceiverTransportMapIterator;
+
+// A receiver (address) entry
+class LBMLBTRUReceiverEntry : public QTreeWidgetItem
+{
+ public:
+ LBMLBTRUReceiverEntry(const QString & receiver_address);
+ virtual ~LBMLBTRUReceiverEntry(void);
+ void processPacket(const packet_info * pinfo, const lbm_lbtru_tap_info_t * tap_info);
+
+ private:
+ LBMLBTRUReceiverEntry(void) { }
+ void fillItem(void);
+ QString m_address;
+ QString m_transport;
+ guint64 m_nak_frames;
+ guint64 m_nak_count;
+ guint64 m_nak_bytes;
+ guint64 m_ack_frames;
+ guint64 m_ack_bytes;
+ guint64 m_creq_frames;
+ guint64 m_creq_bytes;
+ nstime_t m_first_frame_timestamp;
+ bool m_first_frame_timestamp_valid;
+ nstime_t m_last_frame_timestamp;
+ LBMLBTRUReceiverTransportMap m_transports;
+};
+
+LBMLBTRUReceiverEntry::LBMLBTRUReceiverEntry(const QString & receiver_address) :
+ QTreeWidgetItem(),
+ m_address(receiver_address),
+ m_nak_frames(0),
+ m_nak_count(0),
+ m_nak_bytes(0),
+ m_ack_frames(0),
+ m_ack_bytes(0),
+ m_creq_frames(0),
+ m_creq_bytes(0),
+ m_first_frame_timestamp_valid(false),
+ m_transports()
+{
+ m_first_frame_timestamp.secs = 0;
+ m_first_frame_timestamp.nsecs = 0;
+ m_last_frame_timestamp.secs = 0;
+ m_last_frame_timestamp.nsecs = 0;
+ setText(Receiver_AddressTransport_Column, m_address);
+}
+
+LBMLBTRUReceiverEntry::~LBMLBTRUReceiverEntry(void)
+{
+ for (LBMLBTRUReceiverTransportMapIterator it = m_transports.begin(); it != m_transports.end(); it++)
+ {
+ delete *it;
+ }
+ m_transports.clear();
+}
+
+void LBMLBTRUReceiverEntry::processPacket(const packet_info * pinfo, const lbm_lbtru_tap_info_t * tap_info)
+{
+ LBMLBTRUReceiverTransportEntry * transport = NULL;
+ LBMLBTRUReceiverTransportMapIterator it;
+
+ if (m_first_frame_timestamp_valid)
+ {
+ if (nstime_cmp(&(pinfo->fd->abs_ts), &m_first_frame_timestamp) < 0)
+ {
+ nstime_copy(&(m_first_frame_timestamp), &(pinfo->fd->abs_ts));
+ }
+ }
+ else
+ {
+ nstime_copy(&(m_first_frame_timestamp), &(pinfo->fd->abs_ts));
+ m_first_frame_timestamp_valid = true;
+ }
+ if (nstime_cmp(&(pinfo->fd->abs_ts), &m_last_frame_timestamp) > 0)
+ {
+ nstime_copy(&(m_last_frame_timestamp), &(pinfo->fd->abs_ts));
+ }
+ switch (tap_info->type)
+ {
+ case LBTRU_PACKET_TYPE_NAK:
+ m_nak_frames++;
+ m_nak_bytes += pinfo->fd->pkt_len;
+ m_nak_count += tap_info->num_sqns;
+ break;
+ case LBTRU_PACKET_TYPE_ACK:
+ m_ack_frames++;
+ m_ack_bytes += pinfo->fd->pkt_len;
+ break;
+ case LBTRU_PACKET_TYPE_CREQ:
+ m_creq_frames++;
+ m_creq_bytes += pinfo->fd->pkt_len;
+ break;
+ }
+
+ it = m_transports.find(tap_info->transport);
+ if (m_transports.end() == it)
+ {
+ transport = new LBMLBTRUReceiverTransportEntry(tap_info->transport);
+ m_transports.insert(tap_info->transport, transport);
+ addChild(transport);
+ sortChildren(Receiver_AddressTransport_Column, Qt::AscendingOrder);
+ }
+ else
+ {
+ transport = it.value();
+ }
+ fillItem();
+ transport->processPacket(pinfo, tap_info);
+}
+
+void LBMLBTRUReceiverEntry::fillItem(void)
+{
+ nstime_t delta;
+
+ nstime_delta(&delta, &m_last_frame_timestamp, &m_first_frame_timestamp);
+ setText(Receiver_NAKFrames_Column, QString("%1").arg(m_nak_frames));
+ setTextAlignment(Receiver_NAKFrames_Column, Qt::AlignRight);
+ setText(Receiver_NAKCount_Column, QString("%1").arg(m_nak_count));
+ setTextAlignment(Receiver_NAKCount_Column, Qt::AlignRight);
+ setText(Receiver_NAKBytes_Column, QString("%1").arg(m_nak_bytes));
+ setTextAlignment(Receiver_NAKBytes_Column, Qt::AlignRight);
+ setText(Receiver_NAKFramesCount_Column, QString("%1/%2").arg(m_nak_frames).arg(m_nak_count));
+ setTextAlignment(Receiver_NAKFramesCount_Column, Qt::AlignHCenter);
+ setText(Receiver_NAKCountBytes_Column, QString("%1/%2").arg(m_nak_count).arg(m_nak_bytes));
+ setTextAlignment(Receiver_NAKCountBytes_Column, Qt::AlignHCenter);
+ setText(Receiver_NAKFramesBytes_Column, QString("%1/%2").arg(m_nak_frames).arg(m_nak_bytes));
+ setTextAlignment(Receiver_NAKFramesBytes_Column, Qt::AlignHCenter);
+ setText(Receiver_NAKFramesCountBytes_Column, QString("%1/%2/%3").arg(m_nak_frames).arg(m_nak_count).arg(m_nak_bytes));
+ setTextAlignment(Receiver_NAKFramesCountBytes_Column, Qt::AlignHCenter);
+ setText(Receiver_NAKRate_Column, format_rate(delta, m_nak_bytes));
+ setTextAlignment(Receiver_NAKRate_Column, Qt::AlignRight);
+ setText(Receiver_ACKFrames_Column, QString("%1").arg(m_ack_frames));
+ setTextAlignment(Receiver_ACKFrames_Column, Qt::AlignRight);
+ setText(Receiver_ACKBytes_Column, QString("%1").arg(m_ack_bytes));
+ setTextAlignment(Receiver_ACKBytes_Column, Qt::AlignRight);
+ setText(Receiver_ACKFramesBytes_Column, QString("%1/%2").arg(m_ack_frames).arg(m_ack_bytes));
+ setTextAlignment(Receiver_ACKFramesBytes_Column, Qt::AlignHCenter);
+ setText(Receiver_ACKRate_Column, format_rate(delta, m_ack_bytes));
+ setTextAlignment(Receiver_ACKRate_Column, Qt::AlignRight);
+ setText(Receiver_CREQFrames_Column, QString("%1").arg(m_creq_frames));
+ setTextAlignment(Receiver_CREQFrames_Column, Qt::AlignRight);
+ setText(Receiver_CREQBytes_Column, QString("%1").arg(m_creq_bytes));
+ setTextAlignment(Receiver_CREQBytes_Column, Qt::AlignRight);
+ setText(Receiver_CREQFramesBytes_Column, QString("%1/%2").arg(m_creq_frames).arg(m_creq_bytes));
+ setTextAlignment(Receiver_CREQFramesBytes_Column, Qt::AlignHCenter);
+ setText(Receiver_CREQRate_Column, format_rate(delta, m_creq_bytes));
+ setTextAlignment(Receiver_CREQRate_Column, Qt::AlignRight);
+}
+
+typedef QMap<QString, LBMLBTRUReceiverEntry *> LBMLBTRUReceiverMap;
+typedef QMap<QString, LBMLBTRUReceiverEntry *>::iterator LBMLBTRUReceiverMapIterator;
+
+class LBMLBTRUTransportDialogInfo
+{
+ public:
+ LBMLBTRUTransportDialogInfo(void);
+ ~LBMLBTRUTransportDialogInfo(void);
+ void setDialog(LBMLBTRUTransportDialog * dialog);
+ LBMLBTRUTransportDialog * getDialog(void);
+ void processPacket(const packet_info * pinfo, const lbm_lbtru_tap_info_t * tap_info);
+ void clearMaps(void);
+
+ private:
+ LBMLBTRUTransportDialog * m_dialog;
+ LBMLBTRUSourceMap m_sources;
+ LBMLBTRUReceiverMap m_receivers;
+};
+
+LBMLBTRUTransportDialogInfo::LBMLBTRUTransportDialogInfo(void) :
+ m_dialog(NULL),
+ m_sources(),
+ m_receivers()
+{
+}
+
+LBMLBTRUTransportDialogInfo::~LBMLBTRUTransportDialogInfo(void)
+{
+ clearMaps();
+}
+
+void LBMLBTRUTransportDialogInfo::setDialog(LBMLBTRUTransportDialog * dialog)
+{
+ m_dialog = dialog;
+}
+
+LBMLBTRUTransportDialog * LBMLBTRUTransportDialogInfo::getDialog(void)
+{
+ return (m_dialog);
+}
+
+void LBMLBTRUTransportDialogInfo::processPacket(const packet_info * pinfo, const lbm_lbtru_tap_info_t * tap_info)
+{
+ switch (tap_info->type)
+ {
+ case LBTRU_PACKET_TYPE_DATA:
+ case LBTRU_PACKET_TYPE_SM:
+ case LBTRU_PACKET_TYPE_NCF:
+ case LBTRU_PACKET_TYPE_RST:
+ {
+ LBMLBTRUSourceEntry * source = NULL;
+ LBMLBTRUSourceMapIterator it;
+ QString src_address = QString(address_to_str(wmem_packet_scope(), &(pinfo->src)));
+
+ it = m_sources.find(src_address);
+ if (m_sources.end() == it)
+ {
+ QTreeWidgetItem * parent = NULL;
+ Ui::LBMLBTRUTransportDialog * ui = NULL;
+
+ source = new LBMLBTRUSourceEntry(src_address);
+ it = m_sources.insert(src_address, source);
+ ui = m_dialog->getUI();
+ ui->sources_TreeWidget->addTopLevelItem(source);
+ parent = ui->sources_TreeWidget->invisibleRootItem();
+ parent->sortChildren(Source_AddressTransport_Column, Qt::AscendingOrder);
+ ui->sources_TreeWidget->resizeColumnToContents(Source_AddressTransport_Column);
+ }
+ else
+ {
+ source = it.value();
+ }
+ source->processPacket(pinfo, tap_info);
+ }
+ break;
+ case LBTRU_PACKET_TYPE_NAK:
+ case LBTRU_PACKET_TYPE_ACK:
+ case LBTRU_PACKET_TYPE_CREQ:
+ {
+ LBMLBTRUReceiverEntry * receiver = NULL;
+ LBMLBTRUReceiverMapIterator it;
+ QString src_address = QString(address_to_str(wmem_packet_scope(), &(pinfo->src)));
+
+ it = m_receivers.find(src_address);
+ if (m_receivers.end() == it)
+ {
+ QTreeWidgetItem * parent = NULL;
+ Ui::LBMLBTRUTransportDialog * ui = NULL;
+
+ receiver = new LBMLBTRUReceiverEntry(src_address);
+ it = m_receivers.insert(src_address, receiver);
+ ui = m_dialog->getUI();
+ ui->receivers_TreeWidget->addTopLevelItem(receiver);
+ parent = ui->receivers_TreeWidget->invisibleRootItem();
+ parent->sortChildren(Receiver_AddressTransport_Column, Qt::AscendingOrder);
+ ui->receivers_TreeWidget->resizeColumnToContents(Receiver_AddressTransport_Column);
+ }
+ else
+ {
+ receiver = it.value();
+ }
+ receiver->processPacket(pinfo, tap_info);
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+void LBMLBTRUTransportDialogInfo::clearMaps(void)
+{
+ for (LBMLBTRUSourceMapIterator it = m_sources.begin(); it != m_sources.end(); it++)
+ {
+ delete *it;
+ }
+ m_sources.clear();
+
+ for (LBMLBTRUReceiverMapIterator it = m_receivers.begin(); it != m_receivers.end(); it++)
+ {
+ delete *it;
+ }
+ m_receivers.clear();
+}
+
+LBMLBTRUTransportDialog::LBMLBTRUTransportDialog(QWidget * parent, capture_file * cfile) :
+ QDialog(parent),
+ m_ui(new Ui::LBMLBTRUTransportDialog),
+ m_dialog_info(NULL),
+ m_capture_file(cfile),
+ m_current_source_transport(NULL),
+ m_current_receiver_transport(NULL),
+ m_source_context_menu(NULL),
+ m_source_header(NULL)
+{
+ m_ui->setupUi(this);
+
+ m_dialog_info = new LBMLBTRUTransportDialogInfo();
+ m_ui->tabWidget->setCurrentIndex(0);
+ m_ui->sources_detail_ComboBox->setCurrentIndex(0);
+ m_ui->sources_detail_transport_Label->setText(QString(" "));
+ m_ui->sources_stackedWidget->setCurrentIndex(0);
+ m_ui->receivers_detail_ComboBox->setCurrentIndex(0);
+ m_ui->receivers_detail_transport_Label->setText(QString(" "));
+ m_ui->receivers_stackedWidget->setCurrentIndex(0);
+
+ // Setup the source context menu
+ m_source_header = m_ui->sources_TreeWidget->header();
+ m_source_context_menu = new QMenu(m_source_header);
+
+ m_source_context_menu->addAction(m_ui->action_SourceAutoResizeColumns);
+ connect(m_ui->action_SourceAutoResizeColumns, SIGNAL(triggered()), this, SLOT(actionSourceAutoResizeColumns_triggered()));
+ m_source_context_menu->addSeparator();
+
+ m_ui->action_SourceDataFrames->setChecked(true);
+ m_source_context_menu->addAction(m_ui->action_SourceDataFrames);
+ connect(m_ui->action_SourceDataFrames, SIGNAL(triggered(bool)), this, SLOT(actionSourceDataFrames_triggered(bool)));
+ m_ui->action_SourceDataBytes->setChecked(true);
+ m_source_context_menu->addAction(m_ui->action_SourceDataBytes);
+ connect(m_ui->action_SourceDataBytes, SIGNAL(triggered(bool)), this, SLOT(actionSourceDataBytes_triggered(bool)));
+ m_ui->action_SourceDataFramesBytes->setChecked(false);
+ m_source_context_menu->addAction(m_ui->action_SourceDataFramesBytes);
+ connect(m_ui->action_SourceDataFramesBytes, SIGNAL(triggered(bool)), this, SLOT(actionSourceDataFramesBytes_triggered(bool)));
+ m_ui->action_SourceDataRate->setChecked(true);
+ m_source_context_menu->addAction(m_ui->action_SourceDataRate);
+ connect(m_ui->action_SourceDataRate, SIGNAL(triggered(bool)), this, SLOT(actionSourceDataRate_triggered(bool)));
+
+ m_ui->action_SourceRXDataFrames->setChecked(true);
+ m_source_context_menu->addAction(m_ui->action_SourceRXDataFrames);
+ connect(m_ui->action_SourceRXDataFrames, SIGNAL(triggered(bool)), this, SLOT(actionSourceRXDataFrames_triggered(bool)));
+ m_ui->action_SourceRXDataBytes->setChecked(true);
+ m_source_context_menu->addAction(m_ui->action_SourceRXDataBytes);
+ connect(m_ui->action_SourceRXDataBytes, SIGNAL(triggered(bool)), this, SLOT(actionSourceRXDataBytes_triggered(bool)));
+ m_ui->action_SourceRXDataFramesBytes->setChecked(false);
+ m_source_context_menu->addAction(m_ui->action_SourceRXDataFramesBytes);
+ connect(m_ui->action_SourceRXDataFramesBytes, SIGNAL(triggered(bool)), this, SLOT(actionSourceRXDataFramesBytes_triggered(bool)));
+ m_ui->action_SourceRXDataRate->setChecked(true);
+ m_source_context_menu->addAction(m_ui->action_SourceRXDataRate);
+ connect(m_ui->action_SourceRXDataRate, SIGNAL(triggered(bool)), this, SLOT(actionSourceRXDataRate_triggered(bool)));
+
+ m_ui->action_SourceNCFFrames->setChecked(true);
+ m_source_context_menu->addAction(m_ui->action_SourceNCFFrames);
+ connect(m_ui->action_SourceNCFFrames, SIGNAL(triggered(bool)), this, SLOT(actionSourceNCFFrames_triggered(bool)));
+ m_ui->action_SourceNCFCount->setChecked(true);
+ m_source_context_menu->addAction(m_ui->action_SourceNCFCount);
+ connect(m_ui->action_SourceNCFCount, SIGNAL(triggered(bool)), this, SLOT(actionSourceNCFCount_triggered(bool)));
+ m_ui->action_SourceNCFBytes->setChecked(true);
+ m_source_context_menu->addAction(m_ui->action_SourceNCFBytes);
+ connect(m_ui->action_SourceNCFBytes, SIGNAL(triggered(bool)), this, SLOT(actionSourceNCFBytes_triggered(bool)));
+ m_ui->action_SourceNCFFramesBytes->setChecked(false);
+ m_source_context_menu->addAction(m_ui->action_SourceNCFFramesBytes);
+ connect(m_ui->action_SourceNCFFramesBytes, SIGNAL(triggered(bool)), this, SLOT(actionSourceNCFFramesBytes_triggered(bool)));
+ m_ui->action_SourceNCFCountBytes->setChecked(false);
+ m_source_context_menu->addAction(m_ui->action_SourceNCFCountBytes);
+ connect(m_ui->action_SourceNCFCountBytes, SIGNAL(triggered(bool)), this, SLOT(actionSourceNCFCountBytes_triggered(bool)));
+ m_ui->action_SourceNCFFramesCount->setChecked(false);
+ m_source_context_menu->addAction(m_ui->action_SourceNCFFramesCount);
+ connect(m_ui->action_SourceNCFFramesCount, SIGNAL(triggered(bool)), this, SLOT(actionSourceNCFFramesCount_triggered(bool)));
+ m_ui->action_SourceNCFFramesCountBytes->setChecked(false);
+ m_source_context_menu->addAction(m_ui->action_SourceNCFFramesCountBytes);
+ connect(m_ui->action_SourceNCFFramesCountBytes, SIGNAL(triggered(bool)), this, SLOT(actionSourceNCFFramesCountBytes_triggered(bool)));
+ m_ui->action_SourceNCFRate->setChecked(true);
+ m_source_context_menu->addAction(m_ui->action_SourceNCFRate);
+ connect(m_ui->action_SourceNCFRate, SIGNAL(triggered(bool)), this, SLOT(actionSourceNCFRate_triggered(bool)));
+
+ m_ui->action_SourceSMFrames->setChecked(true);
+ m_source_context_menu->addAction(m_ui->action_SourceSMFrames);
+ connect(m_ui->action_SourceSMFrames, SIGNAL(triggered(bool)), this, SLOT(actionSourceSMFrames_triggered(bool)));
+ m_ui->action_SourceSMBytes->setChecked(true);
+ m_source_context_menu->addAction(m_ui->action_SourceSMBytes);
+ connect(m_ui->action_SourceSMBytes, SIGNAL(triggered(bool)), this, SLOT(actionSourceSMBytes_triggered(bool)));
+ m_ui->action_SourceSMFramesBytes->setChecked(false);
+ m_source_context_menu->addAction(m_ui->action_SourceSMFramesBytes);
+ connect(m_ui->action_SourceSMFramesBytes, SIGNAL(triggered(bool)), this, SLOT(actionSourceSMFramesBytes_triggered(bool)));
+ m_ui->action_SourceSMRate->setChecked(true);
+ m_source_context_menu->addAction(m_ui->action_SourceSMRate);
+ connect(m_ui->action_SourceSMRate, SIGNAL(triggered(bool)), this, SLOT(actionSourceSMRate_triggered(bool)));
+
+ m_source_header->setContextMenuPolicy(Qt::CustomContextMenu);
+ connect(m_source_header, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(custom_source_context_menuRequested(const QPoint &)));
+
+ // Setup the receiver context menu
+ m_receiver_header = m_ui->receivers_TreeWidget->header();
+ m_receiver_context_menu = new QMenu(m_receiver_header);
+
+ m_receiver_context_menu->addAction(m_ui->action_ReceiverAutoResizeColumns);
+ connect(m_ui->action_ReceiverAutoResizeColumns, SIGNAL(triggered()), this, SLOT(actionReceiverAutoResizeColumns_triggered()));
+ m_receiver_context_menu->addSeparator();
+
+ m_ui->action_ReceiverNAKFrames->setChecked(true);
+ m_receiver_context_menu->addAction(m_ui->action_ReceiverNAKFrames);
+ connect(m_ui->action_ReceiverNAKFrames, SIGNAL(triggered(bool)), this, SLOT(actionReceiverNAKFrames_triggered(bool)));
+ m_ui->action_ReceiverNAKCount->setChecked(true);
+ m_receiver_context_menu->addAction(m_ui->action_ReceiverNAKCount);
+ connect(m_ui->action_ReceiverNAKCount, SIGNAL(triggered(bool)), this, SLOT(actionReceiverNAKCount_triggered(bool)));
+ m_ui->action_ReceiverNAKBytes->setChecked(true);
+ m_receiver_context_menu->addAction(m_ui->action_ReceiverNAKBytes);
+ connect(m_ui->action_ReceiverNAKBytes, SIGNAL(triggered(bool)), this, SLOT(actionReceiverNAKBytes_triggered(bool)));
+ m_ui->action_ReceiverNAKFramesBytes->setChecked(false);
+ m_receiver_context_menu->addAction(m_ui->action_ReceiverNAKFramesBytes);
+ connect(m_ui->action_ReceiverNAKFramesBytes, SIGNAL(triggered(bool)), this, SLOT(actionReceiverNAKFramesBytes_triggered(bool)));
+ m_ui->action_ReceiverNAKCountBytes->setChecked(false);
+ m_receiver_context_menu->addAction(m_ui->action_ReceiverNAKCountBytes);
+ connect(m_ui->action_ReceiverNAKCountBytes, SIGNAL(triggered(bool)), this, SLOT(actionReceiverNAKCountBytes_triggered(bool)));
+ m_ui->action_ReceiverNAKFramesCount->setChecked(false);
+ m_receiver_context_menu->addAction(m_ui->action_ReceiverNAKFramesCount);
+ connect(m_ui->action_ReceiverNAKFramesCount, SIGNAL(triggered(bool)), this, SLOT(actionReceiverNAKFramesCount_triggered(bool)));
+ m_ui->action_ReceiverNAKFramesCountBytes->setChecked(false);
+ m_receiver_context_menu->addAction(m_ui->action_ReceiverNAKFramesCountBytes);
+ connect(m_ui->action_ReceiverNAKFramesCountBytes, SIGNAL(triggered(bool)), this, SLOT(actionReceiverNAKFramesCountBytes_triggered(bool)));
+ m_ui->action_ReceiverNAKRate->setChecked(true);
+ m_receiver_context_menu->addAction(m_ui->action_ReceiverNAKRate);
+ connect(m_ui->action_ReceiverNAKRate, SIGNAL(triggered(bool)), this, SLOT(actionReceiverNAKRate_triggered(bool)));
+
+ m_ui->action_ReceiverACKFrames->setChecked(true);
+ m_receiver_context_menu->addAction(m_ui->action_ReceiverACKFrames);
+ connect(m_ui->action_ReceiverACKFrames, SIGNAL(triggered(bool)), this, SLOT(actionReceiverACKFrames_triggered(bool)));
+ m_ui->action_ReceiverACKBytes->setChecked(true);
+ m_receiver_context_menu->addAction(m_ui->action_ReceiverACKBytes);
+ connect(m_ui->action_ReceiverACKBytes, SIGNAL(triggered(bool)), this, SLOT(actionReceiverACKBytes_triggered(bool)));
+ m_ui->action_ReceiverACKFramesBytes->setChecked(false);
+ m_receiver_context_menu->addAction(m_ui->action_ReceiverACKFramesBytes);
+ connect(m_ui->action_ReceiverACKFramesBytes, SIGNAL(triggered(bool)), this, SLOT(actionReceiverACKFramesBytes_triggered(bool)));
+ m_ui->action_ReceiverACKRate->setChecked(true);
+ m_receiver_context_menu->addAction(m_ui->action_ReceiverACKRate);
+ connect(m_ui->action_ReceiverACKRate, SIGNAL(triggered(bool)), this, SLOT(actionReceiverACKRate_triggered(bool)));
+
+ m_ui->action_ReceiverCREQFrames->setChecked(true);
+ m_receiver_context_menu->addAction(m_ui->action_ReceiverCREQFrames);
+ connect(m_ui->action_ReceiverCREQFrames, SIGNAL(triggered(bool)), this, SLOT(actionReceiverCREQFrames_triggered(bool)));
+ m_ui->action_ReceiverCREQBytes->setChecked(true);
+ m_receiver_context_menu->addAction(m_ui->action_ReceiverCREQBytes);
+ connect(m_ui->action_ReceiverCREQBytes, SIGNAL(triggered(bool)), this, SLOT(actionReceiverCREQBytes_triggered(bool)));
+ m_ui->action_ReceiverCREQFramesBytes->setChecked(false);
+ m_receiver_context_menu->addAction(m_ui->action_ReceiverCREQFramesBytes);
+ connect(m_ui->action_ReceiverCREQFramesBytes, SIGNAL(triggered(bool)), this, SLOT(actionReceiverCREQFramesBytes_triggered(bool)));
+ m_ui->action_ReceiverCREQRate->setChecked(true);
+ m_receiver_context_menu->addAction(m_ui->action_ReceiverCREQRate);
+ connect(m_ui->action_ReceiverCREQRate, SIGNAL(triggered(bool)), this, SLOT(actionReceiverCREQRate_triggered(bool)));
+
+ m_receiver_header->setContextMenuPolicy(Qt::CustomContextMenu);
+ connect(m_receiver_header, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(custom_receiver_context_menuRequested(const QPoint &)));
+
+ // Setup the source tree widget header
+ m_ui->sources_TreeWidget->setColumnHidden(Source_DataFramesBytes_Column, true);
+ m_ui->sources_TreeWidget->setColumnHidden(Source_RXDataFramesBytes_Column, true);
+ m_ui->sources_TreeWidget->setColumnHidden(Source_NCFFramesBytes_Column, true);
+ m_ui->sources_TreeWidget->setColumnHidden(Source_NCFCountBytes_Column, true);
+ m_ui->sources_TreeWidget->setColumnHidden(Source_NCFFramesCount_Column, true);
+ m_ui->sources_TreeWidget->setColumnHidden(Source_NCFFramesCountBytes_Column, true);
+ m_ui->sources_TreeWidget->setColumnHidden(Source_SMFramesBytes_Column, true);
+ m_ui->sources_TreeWidget->setColumnHidden(Source_RSTFramesBytes_Column, true);
+
+ // Setup the receiver tree widget header
+ m_ui->receivers_TreeWidget->setColumnHidden(Receiver_NAKFramesBytes_Column, true);
+ m_ui->receivers_TreeWidget->setColumnHidden(Receiver_NAKCountBytes_Column, true);
+ m_ui->receivers_TreeWidget->setColumnHidden(Receiver_NAKFramesCount_Column, true);
+ m_ui->receivers_TreeWidget->setColumnHidden(Receiver_NAKFramesCountBytes_Column, true);
+ m_ui->receivers_TreeWidget->setColumnHidden(Receiver_ACKFramesBytes_Column, true);
+ m_ui->receivers_TreeWidget->setColumnHidden(Receiver_CREQFramesBytes_Column, true);
+
+ connect(this, SIGNAL(accepted()), this, SLOT(closeDialog()));
+ connect(this, SIGNAL(rejected()), this, SLOT(closeDialog()));
+ fillTree();
+}
+
+LBMLBTRUTransportDialog::~LBMLBTRUTransportDialog(void)
+{
+ resetSourcesDetail();
+ resetSources();
+ resetReceiversDetail();
+ resetReceivers();
+ if (m_dialog_info != NULL)
+ {
+ delete m_dialog_info;
+ m_dialog_info = NULL;
+ }
+ delete m_source_context_menu;
+ m_source_context_menu = NULL;
+ delete m_ui;
+ m_ui = NULL;
+ m_capture_file = NULL;
+}
+
+void LBMLBTRUTransportDialog::setCaptureFile(capture_file * cfile)
+{
+ if (cfile == NULL) // We only want to know when the file closes.
+ {
+ m_capture_file = NULL;
+ m_ui->displayFilterLineEdit->setEnabled(false);
+ m_ui->applyFilterButton->setEnabled(false);
+ }
+}
+
+void LBMLBTRUTransportDialog::resetSources(void)
+{
+ while (m_ui->sources_TreeWidget->takeTopLevelItem(0) != NULL)
+ {}
+}
+
+void LBMLBTRUTransportDialog::resetReceivers(void)
+{
+ while (m_ui->receivers_TreeWidget->takeTopLevelItem(0) != NULL)
+ {}
+}
+
+void LBMLBTRUTransportDialog::resetSourcesDetail(void)
+{
+ while (m_ui->sources_detail_sqn_TreeWidget->takeTopLevelItem(0) != NULL)
+ {}
+ while (m_ui->sources_detail_ncf_sqn_TreeWidget->takeTopLevelItem(0) != NULL)
+ {}
+ while (m_ui->sources_detail_rst_TreeWidget->takeTopLevelItem(0) != NULL)
+ {}
+ m_ui->sources_detail_transport_Label->setText(QString(" "));
+ m_current_source_transport = NULL;
+}
+
+void LBMLBTRUTransportDialog::resetReceiversDetail(void)
+{
+ while (m_ui->receivers_detail_sqn_TreeWidget->takeTopLevelItem(0) != NULL)
+ {}
+ while (m_ui->receivers_detail_reason_TreeWidget->takeTopLevelItem(0) != NULL)
+ {}
+ m_ui->receivers_detail_transport_Label->setText(QString(" "));
+ m_current_receiver_transport = NULL;
+}
+
+void LBMLBTRUTransportDialog::fillTree(void)
+{
+ GString * error_string;
+
+ if (m_capture_file == NULL)
+ {
+ return;
+ }
+ m_dialog_info->setDialog(this);
+
+ error_string = register_tap_listener("lbtru",
+ (void *)m_dialog_info,
+ m_ui->displayFilterLineEdit->text().toUtf8().constData(),
+ TL_REQUIRES_COLUMNS,
+ resetTap,
+ tapPacket,
+ drawTreeItems);
+ if (error_string)
+ {
+ QMessageBox::critical(this, tr("LBT-RU Statistics failed to attach to tap"),
+ error_string->str);
+ g_string_free(error_string, TRUE);
+ reject();
+ }
+
+ cf_retap_packets(m_capture_file);
+ drawTreeItems(&m_dialog_info);
+ remove_tap_listener((void *)m_dialog_info);
+}
+
+void LBMLBTRUTransportDialog::resetTap(void * tap_data)
+{
+ LBMLBTRUTransportDialogInfo * info = (LBMLBTRUTransportDialogInfo *)tap_data;
+ LBMLBTRUTransportDialog * dialog = info->getDialog();
+ if (dialog == NULL)
+ {
+ return;
+ }
+ dialog->resetSourcesDetail();
+ dialog->resetSources();
+ dialog->resetReceiversDetail();
+ dialog->resetReceivers();
+ info->clearMaps();
+}
+
+gboolean LBMLBTRUTransportDialog::tapPacket(void * tap_data, packet_info * pinfo, epan_dissect_t * edt, const void * tap_info)
+{
+ Q_UNUSED(edt)
+
+ if (pinfo->fd->flags.passed_dfilter == 1)
+ {
+ const lbm_lbtru_tap_info_t * tapinfo = (const lbm_lbtru_tap_info_t *)tap_info;
+ LBMLBTRUTransportDialogInfo * info = (LBMLBTRUTransportDialogInfo *)tap_data;
+
+ info->processPacket(pinfo, tapinfo);
+ }
+ return (TRUE);
+}
+
+void LBMLBTRUTransportDialog::drawTreeItems(void * tap_data)
+{
+ Q_UNUSED(tap_data)
+}
+
+void LBMLBTRUTransportDialog::on_applyFilterButton_clicked(void)
+{
+ fillTree();
+}
+
+void LBMLBTRUTransportDialog::closeDialog(void)
+{
+ delete this;
+}
+
+void LBMLBTRUTransportDialog::sourcesDetailCurrentChanged(int index)
+{
+ // Index 0: Data
+ // Index 1: RX data
+ // Index 2: NCF
+ // Index 3: SM
+ // Index 4: RST
+ switch (index)
+ {
+ case 0:
+ case 1:
+ case 3:
+ m_ui->sources_stackedWidget->setCurrentIndex(0);
+ break;
+ case 2:
+ m_ui->sources_stackedWidget->setCurrentIndex(2);
+ break;
+ case 4:
+ m_ui->sources_stackedWidget->setCurrentIndex(1);
+ break;
+ default:
+ return;
+ }
+ sourcesItemClicked(m_current_source_transport, 0);
+}
+
+void LBMLBTRUTransportDialog::sourcesItemClicked(QTreeWidgetItem * item, int column)
+{
+ Q_UNUSED(column)
+
+ LBMLBTRUSourceTransportEntry * transport = dynamic_cast<LBMLBTRUSourceTransportEntry *>(item);
+
+ resetSourcesDetail();
+ if (transport == NULL)
+ {
+ // Must be a source item, ignore it?
+ return;
+ }
+ m_current_source_transport = transport;
+ m_ui->sources_detail_transport_Label->setText(transport->m_transport);
+ int cur_idx = m_ui->sources_detail_ComboBox->currentIndex();
+ switch (cur_idx)
+ {
+ case 0:
+ loadSourceDataDetails(transport);
+ break;
+ case 1:
+ loadSourceRXDataDetails(transport);
+ break;
+ case 2:
+ loadSourceNCFDetails(transport);
+ break;
+ case 3:
+ loadSourceSMDetails(transport);
+ break;
+ case 4:
+ loadSourceRSTDetails(transport);
+ break;
+ default:
+ break;
+ }
+}
+
+void LBMLBTRUTransportDialog::loadSourceDataDetails(LBMLBTRUSourceTransportEntry * transport)
+{
+ for (LBMLBTRUSQNMapIterator it = transport->m_data_sqns.begin(); it != transport->m_data_sqns.end(); it++)
+ {
+ LBMLBTRUSQNEntry * sqn = it.value();
+ m_ui->sources_detail_sqn_TreeWidget->addTopLevelItem(sqn);
+ }
+}
+
+void LBMLBTRUTransportDialog::loadSourceRXDataDetails(LBMLBTRUSourceTransportEntry * transport)
+{
+ for (LBMLBTRUSQNMapIterator it = transport->m_rx_data_sqns.begin(); it != transport->m_rx_data_sqns.end(); it++)
+ {
+ LBMLBTRUSQNEntry * sqn = it.value();
+ m_ui->sources_detail_sqn_TreeWidget->addTopLevelItem(sqn);
+ }
+}
+
+void LBMLBTRUTransportDialog::loadSourceNCFDetails(LBMLBTRUSourceTransportEntry * transport)
+{
+ for (LBMLBTRUNCFSQNMapIterator it = transport->m_ncf_sqns.begin(); it != transport->m_ncf_sqns.end(); it++)
+ {
+ LBMLBTRUNCFSQNEntry * sqn = it.value();
+ m_ui->sources_detail_ncf_sqn_TreeWidget->addTopLevelItem(sqn);
+ }
+}
+
+void LBMLBTRUTransportDialog::loadSourceSMDetails(LBMLBTRUSourceTransportEntry * transport)
+{
+ for (LBMLBTRUSQNMapIterator it = transport->m_sm_sqns.begin(); it != transport->m_sm_sqns.end(); it++)
+ {
+ LBMLBTRUSQNEntry * sqn = it.value();
+ m_ui->sources_detail_sqn_TreeWidget->addTopLevelItem(sqn);
+ }
+}
+
+void LBMLBTRUTransportDialog::loadSourceRSTDetails(LBMLBTRUSourceTransportEntry * transport)
+{
+ for (LBMLBTRURSTReasonMapIterator it = transport->m_rst_reasons.begin(); it != transport->m_rst_reasons.end(); it++)
+ {
+ LBMLBTRURSTReasonEntry * reason = it.value();
+ m_ui->sources_detail_rst_TreeWidget->addTopLevelItem(reason);
+ }
+}
+
+void LBMLBTRUTransportDialog::sourcesDetailItemDoubleClicked(QTreeWidgetItem * item, int column)
+{
+ Q_UNUSED(column)
+
+ LBMLBTRUFrameEntry * frame = dynamic_cast<LBMLBTRUFrameEntry *>(item);
+ if (frame == NULL)
+ {
+ // Must have double-clicked on something other than an expanded frame entry
+ return;
+ }
+ emit goToPacket((int)frame->getFrame());
+}
+
+void LBMLBTRUTransportDialog::receiversDetailCurrentChanged(int index)
+{
+ // Index 0: NAK
+ // Index 1: ACK
+ // Index 2: CREQ
+ switch (index)
+ {
+ case 0:
+ case 1:
+ m_ui->receivers_stackedWidget->setCurrentIndex(0);
+ break;
+ case 2:
+ m_ui->receivers_stackedWidget->setCurrentIndex(1);
+ break;
+ default:
+ return;
+ }
+ receiversItemClicked(m_current_receiver_transport, 0);
+}
+
+void LBMLBTRUTransportDialog::receiversItemClicked(QTreeWidgetItem * item, int column)
+{
+ Q_UNUSED(column)
+
+ LBMLBTRUReceiverTransportEntry * transport = dynamic_cast<LBMLBTRUReceiverTransportEntry *>(item);
+
+ resetReceiversDetail();
+ if (transport == NULL)
+ {
+ // Must be a receiver item, ignore it?
+ return;
+ }
+ m_current_receiver_transport = transport;
+ m_ui->receivers_detail_transport_Label->setText(transport->m_transport);
+ int cur_idx = m_ui->receivers_detail_ComboBox->currentIndex();
+ switch (cur_idx)
+ {
+ case 0:
+ loadReceiverNAKDetails(transport);
+ break;
+ case 1:
+ loadReceiverACKDetails(transport);
+ break;
+ case 2:
+ loadReceiverCREQDetails(transport);
+ break;
+ default:
+ break;
+ }
+}
+
+void LBMLBTRUTransportDialog::loadReceiverNAKDetails(LBMLBTRUReceiverTransportEntry * transport)
+{
+ for (LBMLBTRUSQNMapIterator it = transport->m_nak_sqns.begin(); it != transport->m_nak_sqns.end(); it++)
+ {
+ LBMLBTRUSQNEntry * sqn = it.value();
+ m_ui->receivers_detail_sqn_TreeWidget->addTopLevelItem(sqn);
+ }
+}
+
+void LBMLBTRUTransportDialog::loadReceiverACKDetails(LBMLBTRUReceiverTransportEntry * transport)
+{
+ for (LBMLBTRUSQNMapIterator it = transport->m_ack_sqns.begin(); it != transport->m_ack_sqns.end(); it++)
+ {
+ LBMLBTRUSQNEntry * sqn = it.value();
+ m_ui->receivers_detail_sqn_TreeWidget->addTopLevelItem(sqn);
+ }
+}
+
+void LBMLBTRUTransportDialog::loadReceiverCREQDetails(LBMLBTRUReceiverTransportEntry * transport)
+{
+ for (LBMLBTRUCREQRequestMapIterator it = transport->m_creq_requests.begin(); it != transport->m_creq_requests.end(); it++)
+ {
+ LBMLBTRUCREQRequestEntry * req = it.value();
+ m_ui->receivers_detail_reason_TreeWidget->addTopLevelItem(req);
+ }
+}
+
+void LBMLBTRUTransportDialog::receiversDetailItemDoubleClicked(QTreeWidgetItem * item, int column)
+{
+ Q_UNUSED(column)
+
+ LBMLBTRUFrameEntry * frame = dynamic_cast<LBMLBTRUFrameEntry *>(item);
+ if (frame == NULL)
+ {
+ // Must have double-clicked on something other than an expanded frame entry
+ return;
+ }
+ emit goToPacket((int)frame->getFrame());
+}
+
+void LBMLBTRUTransportDialog::custom_source_context_menuRequested(const QPoint & pos)
+{
+ m_source_context_menu->exec(m_source_header->mapToGlobal(pos));
+}
+
+void LBMLBTRUTransportDialog::actionSourceDataFrames_triggered(bool checked)
+{
+ m_ui->sources_TreeWidget->setColumnHidden(Source_DataFrames_Column, !checked);
+}
+
+void LBMLBTRUTransportDialog::actionSourceDataBytes_triggered(bool checked)
+{
+ m_ui->sources_TreeWidget->setColumnHidden(Source_DataBytes_Column, !checked);
+}
+
+void LBMLBTRUTransportDialog::actionSourceDataFramesBytes_triggered(bool checked)
+{
+ m_ui->sources_TreeWidget->setColumnHidden(Source_DataFramesBytes_Column, !checked);
+}
+
+void LBMLBTRUTransportDialog::actionSourceDataRate_triggered(bool checked)
+{
+ m_ui->sources_TreeWidget->setColumnHidden(Source_DataRate_Column, !checked);
+}
+
+void LBMLBTRUTransportDialog::actionSourceRXDataFrames_triggered(bool checked)
+{
+ m_ui->sources_TreeWidget->setColumnHidden(Source_RXDataFrames_Column, !checked);
+}
+
+void LBMLBTRUTransportDialog::actionSourceRXDataBytes_triggered(bool checked)
+{
+ m_ui->sources_TreeWidget->setColumnHidden(Source_RXDataBytes_Column, !checked);
+}
+
+void LBMLBTRUTransportDialog::actionSourceRXDataFramesBytes_triggered(bool checked)
+{
+ m_ui->sources_TreeWidget->setColumnHidden(Source_RXDataFramesBytes_Column, !checked);
+}
+
+void LBMLBTRUTransportDialog::actionSourceRXDataRate_triggered(bool checked)
+{
+ m_ui->sources_TreeWidget->setColumnHidden(Source_RXDataRate_Column, !checked);
+}
+
+void LBMLBTRUTransportDialog::actionSourceNCFFrames_triggered(bool checked)
+{
+ m_ui->sources_TreeWidget->setColumnHidden(Source_NCFFrames_Column, !checked);
+}
+
+void LBMLBTRUTransportDialog::actionSourceNCFCount_triggered(bool checked)
+{
+ m_ui->sources_TreeWidget->setColumnHidden(Source_NCFCount_Column, !checked);
+}
+
+void LBMLBTRUTransportDialog::actionSourceNCFBytes_triggered(bool checked)
+{
+ m_ui->sources_TreeWidget->setColumnHidden(Source_NCFFrames_Column, !checked);
+}
+
+void LBMLBTRUTransportDialog::actionSourceNCFFramesBytes_triggered(bool checked)
+{
+ m_ui->sources_TreeWidget->setColumnHidden(Source_NCFFramesBytes_Column, !checked);
+}
+
+void LBMLBTRUTransportDialog::actionSourceNCFCountBytes_triggered(bool checked)
+{
+ m_ui->sources_TreeWidget->setColumnHidden(Source_NCFCountBytes_Column, !checked);
+}
+
+void LBMLBTRUTransportDialog::actionSourceNCFFramesCount_triggered(bool checked)
+{
+ m_ui->sources_TreeWidget->setColumnHidden(Source_NCFFramesCount_Column, !checked);
+}
+
+void LBMLBTRUTransportDialog::actionSourceNCFFramesCountBytes_triggered(bool checked)
+{
+ m_ui->sources_TreeWidget->setColumnHidden(Source_NCFFramesCountBytes_Column, !checked);
+}
+
+void LBMLBTRUTransportDialog::actionSourceNCFRate_triggered(bool checked)
+{
+ m_ui->sources_TreeWidget->setColumnHidden(Source_NCFRate_Column, !checked);
+}
+
+void LBMLBTRUTransportDialog::actionSourceSMFrames_triggered(bool checked)
+{
+ m_ui->sources_TreeWidget->setColumnHidden(Source_SMFrames_Column, !checked);
+}
+
+void LBMLBTRUTransportDialog::actionSourceSMBytes_triggered(bool checked)
+{
+ m_ui->sources_TreeWidget->setColumnHidden(Source_SMBytes_Column, !checked);
+}
+
+void LBMLBTRUTransportDialog::actionSourceSMFramesBytes_triggered(bool checked)
+{
+ m_ui->sources_TreeWidget->setColumnHidden(Source_SMFramesBytes_Column, !checked);
+}
+
+void LBMLBTRUTransportDialog::actionSourceSMRate_triggered(bool checked)
+{
+ m_ui->sources_TreeWidget->setColumnHidden(Source_SMRate_Column, !checked);
+}
+
+void LBMLBTRUTransportDialog::actionSourceAutoResizeColumns_triggered(void)
+{
+ m_ui->sources_TreeWidget->resizeColumnToContents(Source_AddressTransport_Column);
+ m_ui->sources_TreeWidget->resizeColumnToContents(Source_DataFrames_Column);
+ m_ui->sources_TreeWidget->resizeColumnToContents(Source_DataBytes_Column);
+ m_ui->sources_TreeWidget->resizeColumnToContents(Source_DataFramesBytes_Column);
+ m_ui->sources_TreeWidget->resizeColumnToContents(Source_DataRate_Column);
+ m_ui->sources_TreeWidget->resizeColumnToContents(Source_RXDataFrames_Column);
+ m_ui->sources_TreeWidget->resizeColumnToContents(Source_RXDataBytes_Column);
+ m_ui->sources_TreeWidget->resizeColumnToContents(Source_RXDataFramesBytes_Column);
+ m_ui->sources_TreeWidget->resizeColumnToContents(Source_RXDataRate_Column);
+ m_ui->sources_TreeWidget->resizeColumnToContents(Source_NCFFrames_Column);
+ m_ui->sources_TreeWidget->resizeColumnToContents(Source_NCFCount_Column);
+ m_ui->sources_TreeWidget->resizeColumnToContents(Source_NCFBytes_Column);
+ m_ui->sources_TreeWidget->resizeColumnToContents(Source_NCFFramesBytes_Column);
+ m_ui->sources_TreeWidget->resizeColumnToContents(Source_NCFCountBytes_Column);
+ m_ui->sources_TreeWidget->resizeColumnToContents(Source_NCFFramesCount_Column);
+ m_ui->sources_TreeWidget->resizeColumnToContents(Source_NCFFramesCountBytes_Column);
+ m_ui->sources_TreeWidget->resizeColumnToContents(Source_NCFRate_Column);
+ m_ui->sources_TreeWidget->resizeColumnToContents(Source_SMFrames_Column);
+ m_ui->sources_TreeWidget->resizeColumnToContents(Source_SMBytes_Column);
+ m_ui->sources_TreeWidget->resizeColumnToContents(Source_SMFramesBytes_Column);
+ m_ui->sources_TreeWidget->resizeColumnToContents(Source_SMRate_Column);
+ m_ui->sources_TreeWidget->resizeColumnToContents(Source_RSTFrames_Column);
+ m_ui->sources_TreeWidget->resizeColumnToContents(Source_RSTBytes_Column);
+ m_ui->sources_TreeWidget->resizeColumnToContents(Source_RSTFramesBytes_Column);
+ m_ui->sources_TreeWidget->resizeColumnToContents(Source_RSTRate_Column);
+}
+
+void LBMLBTRUTransportDialog::custom_receiver_context_menuRequested(const QPoint & pos)
+{
+ m_receiver_context_menu->exec(m_receiver_header->mapToGlobal(pos));
+}
+
+void LBMLBTRUTransportDialog::actionReceiverNAKFrames_triggered(bool checked)
+{
+ m_ui->receivers_TreeWidget->setColumnHidden(Receiver_NAKFrames_Column, !checked);
+}
+
+void LBMLBTRUTransportDialog::actionReceiverNAKCount_triggered(bool checked)
+{
+ m_ui->receivers_TreeWidget->setColumnHidden(Receiver_NAKCount_Column, !checked);
+}
+
+void LBMLBTRUTransportDialog::actionReceiverNAKBytes_triggered(bool checked)
+{
+ m_ui->receivers_TreeWidget->setColumnHidden(Receiver_NAKBytes_Column, !checked);
+}
+
+void LBMLBTRUTransportDialog::actionReceiverNAKFramesCount_triggered(bool checked)
+{
+ m_ui->receivers_TreeWidget->setColumnHidden(Receiver_NAKFramesCount_Column, !checked);
+}
+
+void LBMLBTRUTransportDialog::actionReceiverNAKCountBytes_triggered(bool checked)
+{
+ m_ui->receivers_TreeWidget->setColumnHidden(Receiver_NAKCountBytes_Column, !checked);
+}
+
+void LBMLBTRUTransportDialog::actionReceiverNAKFramesBytes_triggered(bool checked)
+{
+ m_ui->receivers_TreeWidget->setColumnHidden(Receiver_NAKFramesBytes_Column, !checked);
+}
+
+void LBMLBTRUTransportDialog::actionReceiverNAKFramesCountBytes_triggered(bool checked)
+{
+ m_ui->receivers_TreeWidget->setColumnHidden(Receiver_NAKFramesCountBytes_Column, !checked);
+}
+
+void LBMLBTRUTransportDialog::actionReceiverNAKRate_triggered(bool checked)
+{
+ m_ui->receivers_TreeWidget->setColumnHidden(Receiver_NAKRate_Column, !checked);
+}
+
+void LBMLBTRUTransportDialog::actionReceiverACKFrames_triggered(bool checked)
+{
+ m_ui->receivers_TreeWidget->setColumnHidden(Receiver_ACKFrames_Column, !checked);
+}
+
+void LBMLBTRUTransportDialog::actionReceiverACKBytes_triggered(bool checked)
+{
+ m_ui->receivers_TreeWidget->setColumnHidden(Receiver_ACKBytes_Column, !checked);
+}
+
+void LBMLBTRUTransportDialog::actionReceiverACKFramesBytes_triggered(bool checked)
+{
+ m_ui->receivers_TreeWidget->setColumnHidden(Receiver_ACKFramesBytes_Column, !checked);
+}
+
+void LBMLBTRUTransportDialog::actionReceiverACKRate_triggered(bool checked)
+{
+ m_ui->receivers_TreeWidget->setColumnHidden(Receiver_ACKRate_Column, !checked);
+}
+
+void LBMLBTRUTransportDialog::actionReceiverCREQFrames_triggered(bool checked)
+{
+ m_ui->receivers_TreeWidget->setColumnHidden(Receiver_CREQFrames_Column, !checked);
+}
+
+void LBMLBTRUTransportDialog::actionReceiverCREQBytes_triggered(bool checked)
+{
+ m_ui->receivers_TreeWidget->setColumnHidden(Receiver_CREQBytes_Column, !checked);
+}
+
+void LBMLBTRUTransportDialog::actionReceiverCREQFramesBytes_triggered(bool checked)
+{
+ m_ui->receivers_TreeWidget->setColumnHidden(Receiver_CREQFramesBytes_Column, !checked);
+}
+
+void LBMLBTRUTransportDialog::actionReceiverCREQRate_triggered(bool checked)
+{
+ m_ui->receivers_TreeWidget->setColumnHidden(Receiver_CREQRate_Column, !checked);
+}
+
+void LBMLBTRUTransportDialog::actionReceiverAutoResizeColumns_triggered(void)
+{
+ m_ui->receivers_TreeWidget->resizeColumnToContents(Receiver_AddressTransport_Column);
+ m_ui->receivers_TreeWidget->resizeColumnToContents(Receiver_NAKFrames_Column);
+ m_ui->receivers_TreeWidget->resizeColumnToContents(Receiver_NAKCount_Column);
+ m_ui->receivers_TreeWidget->resizeColumnToContents(Receiver_NAKBytes_Column);
+ m_ui->receivers_TreeWidget->resizeColumnToContents(Receiver_NAKFramesBytes_Column);
+ m_ui->receivers_TreeWidget->resizeColumnToContents(Receiver_NAKCountBytes_Column);
+ m_ui->receivers_TreeWidget->resizeColumnToContents(Receiver_NAKFramesCount_Column);
+ m_ui->receivers_TreeWidget->resizeColumnToContents(Receiver_NAKFramesCountBytes_Column);
+ m_ui->receivers_TreeWidget->resizeColumnToContents(Receiver_NAKRate_Column);
+ m_ui->receivers_TreeWidget->resizeColumnToContents(Receiver_ACKFrames_Column);
+ m_ui->receivers_TreeWidget->resizeColumnToContents(Receiver_ACKBytes_Column);
+ m_ui->receivers_TreeWidget->resizeColumnToContents(Receiver_ACKFramesBytes_Column);
+ m_ui->receivers_TreeWidget->resizeColumnToContents(Receiver_ACKRate_Column);
+ m_ui->receivers_TreeWidget->resizeColumnToContents(Receiver_CREQFrames_Column);
+ m_ui->receivers_TreeWidget->resizeColumnToContents(Receiver_CREQBytes_Column);
+ m_ui->receivers_TreeWidget->resizeColumnToContents(Receiver_CREQFramesBytes_Column);
+ m_ui->receivers_TreeWidget->resizeColumnToContents(Receiver_CREQRate_Column);
+}
+
+/*
+ * Editor modelines - http://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vi: set shiftwidth=4 tabstop=4 expandtab:
+ * :indentSize=4:tabSize=4:noTabs=true:
+ */
diff --git a/ui/qt/lbm_lbtru_transport_dialog.h b/ui/qt/lbm_lbtru_transport_dialog.h
new file mode 100644
index 0000000000..b73e1525a7
--- /dev/null
+++ b/ui/qt/lbm_lbtru_transport_dialog.h
@@ -0,0 +1,156 @@
+/* lbm_lbtru_transport_dialog.h
+ *
+ * Copyright (c) 2005-2014 Informatica Corporation. All Rights Reserved.
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef LBM_LBTRU_TRANSPORT_DIALOG_H
+#define LBM_LBTRU_TRANSPORT_DIALOG_H
+
+#include "config.h"
+
+#include <glib.h>
+
+#include "cfile.h"
+#include <epan/packet_info.h>
+#include <QDialog>
+#include <QTreeWidgetItem>
+
+namespace Ui
+{
+ class LBMLBTRUTransportDialog;
+}
+
+class LBMLBTRUTransportDialogInfo;
+class LBMLBTRUSourceTransportEntry;
+class LBMLBTRUReceiverTransportEntry;
+
+class LBMLBTRUTransportDialog : public QDialog
+{
+ Q_OBJECT
+
+ public:
+ explicit LBMLBTRUTransportDialog(QWidget * parent = 0, capture_file * cfile = NULL);
+ Ui::LBMLBTRUTransportDialog * getUI(void)
+ {
+ return (m_ui);
+ }
+ public slots:
+ void setCaptureFile(capture_file * cfile);
+
+ signals:
+ void goToPacket(int packet_num);
+
+ private:
+ Ui::LBMLBTRUTransportDialog * m_ui;
+ LBMLBTRUTransportDialogInfo * m_dialog_info;
+ capture_file * m_capture_file;
+ LBMLBTRUSourceTransportEntry * m_current_source_transport;
+ LBMLBTRUReceiverTransportEntry * m_current_receiver_transport;
+ QMenu * m_source_context_menu;
+ QHeaderView * m_source_header;
+ QMenu * m_receiver_context_menu;
+ QHeaderView * m_receiver_header;
+
+ virtual ~LBMLBTRUTransportDialog(void);
+ void resetSources(void);
+ void resetReceivers(void);
+ void resetSourcesDetail(void);
+ void resetReceiversDetail(void);
+ void fillTree(void);
+ static void resetTap(void * tap_data);
+ static gboolean tapPacket(void * tap_data, packet_info * pinfo, epan_dissect_t * edt, const void * stream_info);
+ static void drawTreeItems(void * tap_data);
+ void loadSourceDataDetails(LBMLBTRUSourceTransportEntry * transport);
+ void loadSourceRXDataDetails(LBMLBTRUSourceTransportEntry * transport);
+ void loadSourceNCFDetails(LBMLBTRUSourceTransportEntry * transport);
+ void loadSourceSMDetails(LBMLBTRUSourceTransportEntry * transport);
+ void loadSourceRSTDetails(LBMLBTRUSourceTransportEntry * transport);
+ void loadReceiverNAKDetails(LBMLBTRUReceiverTransportEntry * transport);
+ void loadReceiverACKDetails(LBMLBTRUReceiverTransportEntry * transport);
+ void loadReceiverCREQDetails(LBMLBTRUReceiverTransportEntry * transport);
+
+ private slots:
+ void closeDialog(void);
+ void on_applyFilterButton_clicked(void);
+
+ void sourcesDetailCurrentChanged(int index);
+ void sourcesItemClicked(QTreeWidgetItem * item, int column);
+ void sourcesDetailItemDoubleClicked(QTreeWidgetItem * item, int column);
+ void receiversDetailCurrentChanged(int index);
+ void receiversItemClicked(QTreeWidgetItem * item, int column);
+ void receiversDetailItemDoubleClicked(QTreeWidgetItem * item, int column);
+
+ void custom_source_context_menuRequested(const QPoint & pos);
+ void actionSourceDataFrames_triggered(bool checked);
+ void actionSourceDataBytes_triggered(bool checked);
+ void actionSourceDataFramesBytes_triggered(bool checked);
+ void actionSourceDataRate_triggered(bool checked);
+ void actionSourceRXDataFrames_triggered(bool checked);
+ void actionSourceRXDataBytes_triggered(bool checked);
+ void actionSourceRXDataFramesBytes_triggered(bool checked);
+ void actionSourceRXDataRate_triggered(bool checked);
+ void actionSourceNCFFrames_triggered(bool checked);
+ void actionSourceNCFCount_triggered(bool checked);
+ void actionSourceNCFBytes_triggered(bool checked);
+ void actionSourceNCFFramesBytes_triggered(bool checked);
+ void actionSourceNCFCountBytes_triggered(bool checked);
+ void actionSourceNCFFramesCount_triggered(bool checked);
+ void actionSourceNCFFramesCountBytes_triggered(bool checked);
+ void actionSourceNCFRate_triggered(bool checked);
+ void actionSourceSMFrames_triggered(bool checked);
+ void actionSourceSMBytes_triggered(bool checked);
+ void actionSourceSMFramesBytes_triggered(bool checked);
+ void actionSourceSMRate_triggered(bool checked);
+ void actionSourceAutoResizeColumns_triggered(void);
+ void custom_receiver_context_menuRequested(const QPoint & pos);
+ void actionReceiverNAKFrames_triggered(bool checked);
+ void actionReceiverNAKCount_triggered(bool checked);
+ void actionReceiverNAKBytes_triggered(bool checked);
+ void actionReceiverNAKFramesCount_triggered(bool checked);
+ void actionReceiverNAKCountBytes_triggered(bool checked);
+ void actionReceiverNAKFramesBytes_triggered(bool checked);
+ void actionReceiverNAKFramesCountBytes_triggered(bool checked);
+ void actionReceiverNAKRate_triggered(bool checked);
+ void actionReceiverACKFrames_triggered(bool checked);
+ void actionReceiverACKBytes_triggered(bool checked);
+ void actionReceiverACKFramesBytes_triggered(bool checked);
+ void actionReceiverACKRate_triggered(bool checked);
+ void actionReceiverCREQFrames_triggered(bool checked);
+ void actionReceiverCREQBytes_triggered(bool checked);
+ void actionReceiverCREQFramesBytes_triggered(bool checked);
+ void actionReceiverCREQRate_triggered(bool checked);
+ void actionReceiverAutoResizeColumns_triggered(void);
+};
+
+#endif
+
+/*
+ * Editor modelines - http://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vi: set shiftwidth=4 tabstop=4 expandtab:
+ * :indentSize=4:tabSize=4:noTabs=true:
+ */
diff --git a/ui/qt/lbm_lbtru_transport_dialog.ui b/ui/qt/lbm_lbtru_transport_dialog.ui
new file mode 100644
index 0000000000..3b2b271152
--- /dev/null
+++ b/ui/qt/lbm_lbtru_transport_dialog.ui
@@ -0,0 +1,1301 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>LBMLBTRUTransportDialog</class>
+ <widget class="QDialog" name="LBMLBTRUTransportDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>872</width>
+ <height>667</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>LBTRU Transport Statistics</string>
+ </property>
+ <property name="sizeGripEnabled">
+ <bool>true</bool>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QTabWidget" name="tabWidget">
+ <property name="currentIndex">
+ <number>0</number>
+ </property>
+ <widget class="QWidget" name="sourcesTab">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <attribute name="title">
+ <string>Sources</string>
+ </attribute>
+ <layout class="QHBoxLayout" name="horizontalLayout_5">
+ <item>
+ <widget class="QSplitter" name="splitter">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="handleWidth">
+ <number>10</number>
+ </property>
+ <widget class="QTreeWidget" name="sources_TreeWidget">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>16777215</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <attribute name="headerDefaultSectionSize">
+ <number>80</number>
+ </attribute>
+ <column>
+ <property name="text">
+ <string>Address/Transport/Client</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Data frames</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Data bytes</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Data frames/bytes</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Data rate</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>RX data frames</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>RX data bytes</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>RX data frames/bytes</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>RX data rate</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>NCF frames</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>NCF count</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>NCF bytes</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>NCF frames/count</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>NCF frames/bytes</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>NCF count/bytes</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>NCF frames/count/bytes</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>NCF rate</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>SM frames</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>SM bytes</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>SM frames/bytes</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>SM rate</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>RST frames</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>RST bytes</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>RST frames/bytes</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>RST rate</string>
+ </property>
+ </column>
+ </widget>
+ <widget class="QWidget" name="layoutWidget">
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>Show</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="sources_detail_ComboBox">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>120</width>
+ <height>0</height>
+ </size>
+ </property>
+ <item>
+ <property name="text">
+ <string>Data SQN</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>RX Data SQN</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>NCF SQN</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>SM SQN</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>RST reason</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_3">
+ <property name="text">
+ <string>details for transport</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="sources_detail_transport_Label">
+ <property name="text">
+ <string>XXXXX:XXX.XXX.XXX.XXX:XXXXX:XXXXXXXX:XXX.XXX.XXX.XXX:XXXXX</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QStackedWidget" name="sources_stackedWidget">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="lineWidth">
+ <number>1</number>
+ </property>
+ <property name="currentIndex">
+ <number>1</number>
+ </property>
+ <widget class="QWidget" name="sources_detail_sqn_page">
+ <layout class="QHBoxLayout" name="horizontalLayout_4">
+ <item>
+ <widget class="QTreeWidget" name="sources_detail_sqn_TreeWidget">
+ <column>
+ <property name="text">
+ <string>SQN</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Count</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Frame</string>
+ </property>
+ </column>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="sources_detail_rst_page">
+ <layout class="QVBoxLayout" name="verticalLayout_4">
+ <item>
+ <widget class="QTreeWidget" name="sources_detail_rst_TreeWidget">
+ <column>
+ <property name="text">
+ <string>Reason</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Count</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Frame</string>
+ </property>
+ </column>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="sources_detail_ncf_sqn_page">
+ <layout class="QHBoxLayout" name="horizontalLayout_6">
+ <item>
+ <widget class="QTreeWidget" name="sources_detail_ncf_sqn_TreeWidget">
+ <column>
+ <property name="text">
+ <string>SQN/Reason</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Count</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Frame</string>
+ </property>
+ </column>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="receiversTab">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <attribute name="title">
+ <string>Receivers</string>
+ </attribute>
+ <layout class="QHBoxLayout" name="horizontalLayout_9">
+ <item>
+ <widget class="QSplitter" name="splitter_2">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="handleWidth">
+ <number>10</number>
+ </property>
+ <widget class="QTreeWidget" name="receivers_TreeWidget">
+ <column>
+ <property name="text">
+ <string>Address/Transport</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>NAK frames</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>NAK count</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>NAK bytes</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>NAK frames/count</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>NAK count/bytes</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>NAK frames/bytes</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>NAK frames/count/bytes</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>NAK rate</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>ACK frames</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>ACK bytes</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>ACK frames/bytes</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>ACK rate</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>CREQ frames</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>CREQ bytes</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>CREQ frames/bytes</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>CREQ rate</string>
+ </property>
+ </column>
+ </widget>
+ <widget class="QWidget" name="layoutWidget_2">
+ <layout class="QVBoxLayout" name="verticalLayout_3">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_3">
+ <item>
+ <widget class="QLabel" name="label_4">
+ <property name="text">
+ <string>Show</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="receivers_detail_ComboBox">
+ <property name="minimumSize">
+ <size>
+ <width>130</width>
+ <height>0</height>
+ </size>
+ </property>
+ <item>
+ <property name="text">
+ <string>NAK SQN</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>ACK SQN</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>CREQ request</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_5">
+ <property name="text">
+ <string>details for transport</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="receivers_detail_transport_Label">
+ <property name="text">
+ <string>XXXXX:XXX.XXX.XXX.XXX:XXXXX:XXXXXXXX:XXX.XXX.XXX.XXX:XXXXX</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QStackedWidget" name="receivers_stackedWidget">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <widget class="QWidget" name="receivers_detail_sqn_page">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <layout class="QHBoxLayout" name="horizontalLayout_7">
+ <item>
+ <widget class="QTreeWidget" name="receivers_detail_sqn_TreeWidget">
+ <column>
+ <property name="text">
+ <string>SQN</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Count</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Frame</string>
+ </property>
+ </column>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="receivers_detail_reason_page">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <layout class="QHBoxLayout" name="horizontalLayout_8">
+ <item>
+ <widget class="QTreeWidget" name="receivers_detail_reason_TreeWidget">
+ <column>
+ <property name="text">
+ <string>Reason</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Count</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Frame</string>
+ </property>
+ </column>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Display filter:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="DisplayFilterEdit" name="displayFilterLineEdit"/>
+ </item>
+ <item>
+ <widget class="QPushButton" name="applyFilterButton">
+ <property name="toolTip">
+ <string>Regenerate statistics using this display filter</string>
+ </property>
+ <property name="text">
+ <string>Apply</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Close|QDialogButtonBox::Help</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ <action name="actionCopyAsCSV">
+ <property name="text">
+ <string>Copy as CSV</string>
+ </property>
+ <property name="toolTip">
+ <string>Copy the tree as CSV</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+C</string>
+ </property>
+ </action>
+ <action name="actionCopyAsYAML">
+ <property name="text">
+ <string>Copy as YAML</string>
+ </property>
+ <property name="toolTip">
+ <string>Copy the tree as YAML</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+Y</string>
+ </property>
+ </action>
+ <action name="action_SourceDataFrames">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>Data frames</string>
+ </property>
+ <property name="toolTip">
+ <string>Show the data frames column</string>
+ </property>
+ </action>
+ <action name="action_SourceDataBytes">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>Data bytes</string>
+ </property>
+ <property name="toolTip">
+ <string>Show the data bytes column</string>
+ </property>
+ </action>
+ <action name="action_SourceDataFramesBytes">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>Data frames/bytes</string>
+ </property>
+ <property name="toolTip">
+ <string>Show the data frames/bytes column</string>
+ </property>
+ </action>
+ <action name="action_SourceDataRate">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>Data rate</string>
+ </property>
+ <property name="toolTip">
+ <string>Show the data rate column</string>
+ </property>
+ </action>
+ <action name="action_SourceRXDataFrames">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>RX data frames</string>
+ </property>
+ <property name="toolTip">
+ <string>Show the RX data frames column</string>
+ </property>
+ </action>
+ <action name="action_SourceRXDataBytes">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>RX data bytes</string>
+ </property>
+ <property name="toolTip">
+ <string>Show the RX data bytes column</string>
+ </property>
+ </action>
+ <action name="action_SourceRXDataFramesBytes">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>RX data frames/bytes</string>
+ </property>
+ <property name="toolTip">
+ <string>Show the RX data frames/bytes column</string>
+ </property>
+ </action>
+ <action name="action_SourceRXDataRate">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>RX data rate</string>
+ </property>
+ <property name="toolTip">
+ <string>Show the RX data rate column</string>
+ </property>
+ </action>
+ <action name="action_SourceNCFFrames">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>NCF frames</string>
+ </property>
+ <property name="toolTip">
+ <string>Show the NCF frames column</string>
+ </property>
+ </action>
+ <action name="action_SourceNCFCount">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>NCF count</string>
+ </property>
+ <property name="toolTip">
+ <string>Show the NCF count column</string>
+ </property>
+ </action>
+ <action name="action_SourceNCFBytes">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>NCF bytes</string>
+ </property>
+ <property name="toolTip">
+ <string>Show the NCF bytes column</string>
+ </property>
+ </action>
+ <action name="action_SourceNCFFramesBytes">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>NCF frames/bytes</string>
+ </property>
+ <property name="toolTip">
+ <string>Show the NCF frames/bytes column</string>
+ </property>
+ </action>
+ <action name="action_SourceNCFCountBytes">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>NCF count/bytes</string>
+ </property>
+ <property name="toolTip">
+ <string>Show the NCF count/bytes column</string>
+ </property>
+ </action>
+ <action name="action_SourceNCFFramesCount">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>NCF frames/count</string>
+ </property>
+ <property name="toolTip">
+ <string>Show the NCF frames/count column</string>
+ </property>
+ </action>
+ <action name="action_SourceNCFFramesCountBytes">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>NCF frames/count/bytes</string>
+ </property>
+ <property name="toolTip">
+ <string>Sow the NCF frames/count/bytes column</string>
+ </property>
+ </action>
+ <action name="action_SourceSMFrames">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>SM frames</string>
+ </property>
+ <property name="toolTip">
+ <string>Show the SM frames column</string>
+ </property>
+ </action>
+ <action name="action_SourceSMBytes">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>SM bytes</string>
+ </property>
+ <property name="toolTip">
+ <string>Show the SM bytes column</string>
+ </property>
+ </action>
+ <action name="action_SourceSMFramesBytes">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>SM frames/bytes</string>
+ </property>
+ <property name="toolTip">
+ <string>Show the SM frames/bytes column</string>
+ </property>
+ </action>
+ <action name="action_SourceSMRate">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>SM rate</string>
+ </property>
+ <property name="toolTip">
+ <string>Show the SM rate column</string>
+ </property>
+ </action>
+ <action name="action_SourceRSTFrames">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>RST frames</string>
+ </property>
+ <property name="toolTip">
+ <string>Show the RST frames column</string>
+ </property>
+ </action>
+ <action name="action_SourceRSTBytes">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>RST bytes</string>
+ </property>
+ <property name="toolTip">
+ <string>Show the RST bytes column</string>
+ </property>
+ </action>
+ <action name="action_SourceRSTFramesBytes">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>RST frames/bytes</string>
+ </property>
+ <property name="toolTip">
+ <string>Show the RST frames/bytes column</string>
+ </property>
+ </action>
+ <action name="action_SourceRSTRate">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>RST rate</string>
+ </property>
+ <property name="toolTip">
+ <string>Show the RST rate column</string>
+ </property>
+ </action>
+ <action name="action_ReceiverNAKFrames">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>NAK frames</string>
+ </property>
+ <property name="toolTip">
+ <string>Show the NAK frames column</string>
+ </property>
+ </action>
+ <action name="action_ReceiverNAKCount">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>NAK count</string>
+ </property>
+ <property name="toolTip">
+ <string>Show the NAK count column</string>
+ </property>
+ </action>
+ <action name="action_ReceiverNAKBytes">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>NAK bytes</string>
+ </property>
+ <property name="toolTip">
+ <string>Show the NAK bytes column</string>
+ </property>
+ </action>
+ <action name="action_ReceiverNAKFramesCount">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>NAK frames/count</string>
+ </property>
+ <property name="toolTip">
+ <string>Show the NAK frames/count column</string>
+ </property>
+ </action>
+ <action name="action_ReceiverNAKCountBytes">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>NAK count/bytes</string>
+ </property>
+ <property name="toolTip">
+ <string>Show the NAK count/bytes column</string>
+ </property>
+ </action>
+ <action name="action_ReceiverNAKFramesBytes">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>NAK frames/bytes</string>
+ </property>
+ <property name="toolTip">
+ <string>Show the NAK frames/bytes column</string>
+ </property>
+ </action>
+ <action name="action_ReceiverNAKFramesCountBytes">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>NAK frames/count/bytes</string>
+ </property>
+ <property name="toolTip">
+ <string>Show the NAK frames/count/bytes column</string>
+ </property>
+ </action>
+ <action name="action_ReceiverNAKRate">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>NAK rate</string>
+ </property>
+ <property name="toolTip">
+ <string>Show the NAK rate column</string>
+ </property>
+ </action>
+ <action name="action_ReceiverACKFrames">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>ACK frames</string>
+ </property>
+ <property name="toolTip">
+ <string>Show the ACK frames column</string>
+ </property>
+ </action>
+ <action name="action_ReceiverACKBytes">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>ACK bytes</string>
+ </property>
+ <property name="toolTip">
+ <string>Show the ACK bytes column</string>
+ </property>
+ </action>
+ <action name="action_ReceiverACKFramesBytes">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>ACK frames/bytes</string>
+ </property>
+ <property name="toolTip">
+ <string>Show the ACK frames/bytes column</string>
+ </property>
+ </action>
+ <action name="action_ReceiverACKRate">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>ACK rate</string>
+ </property>
+ <property name="toolTip">
+ <string>Show the ACK rate column</string>
+ </property>
+ </action>
+ <action name="action_ReceiverCREQFrames">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>CREQ frames</string>
+ </property>
+ <property name="toolTip">
+ <string>Show the CREQ frames column</string>
+ </property>
+ </action>
+ <action name="action_ReceiverCREQBytes">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>CREQ bytes</string>
+ </property>
+ <property name="toolTip">
+ <string>Show the CREQ bytes column</string>
+ </property>
+ </action>
+ <action name="action_ReceiverCREQFramesBytes">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>CREQ frames/bytes</string>
+ </property>
+ <property name="toolTip">
+ <string>Show the CREQ frames/bytes column</string>
+ </property>
+ </action>
+ <action name="action_ReceiverCREQRate">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>CREQ rate</string>
+ </property>
+ <property name="toolTip">
+ <string>Show the CREQ rate column</string>
+ </property>
+ </action>
+ <action name="action_SourceAutoResizeColumns">
+ <property name="text">
+ <string>Auto-resize columns to content</string>
+ </property>
+ <property name="toolTip">
+ <string>Resize columns to content size</string>
+ </property>
+ </action>
+ <action name="action_ReceiverAutoResizeColumns">
+ <property name="text">
+ <string>Auto-resize columns to content</string>
+ </property>
+ <property name="toolTip">
+ <string>Resize columns to content size</string>
+ </property>
+ </action>
+ <action name="action_SourceNCFRate">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>NCF rate</string>
+ </property>
+ <property name="toolTip">
+ <string>Show the NCF rate column</string>
+ </property>
+ </action>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>DisplayFilterEdit</class>
+ <extends>QLineEdit</extends>
+ <header location="global">display_filter_edit.h</header>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>LBMLBTRUTransportDialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>262</x>
+ <y>659</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>157</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>LBMLBTRUTransportDialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>330</x>
+ <y>659</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>286</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>sources_detail_ComboBox</sender>
+ <signal>currentIndexChanged(int)</signal>
+ <receiver>LBMLBTRUTransportDialog</receiver>
+ <slot>sourcesDetailCurrentChanged(int)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>175</x>
+ <y>315</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>446</x>
+ <y>310</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>sources_TreeWidget</sender>
+ <signal>itemClicked(QTreeWidgetItem*,int)</signal>
+ <receiver>LBMLBTRUTransportDialog</receiver>
+ <slot>sourcesItemClicked(QTreeWidgetItem*,int)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>440</x>
+ <y>149</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>446</x>
+ <y>310</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>sources_detail_sqn_TreeWidget</sender>
+ <signal>itemDoubleClicked(QTreeWidgetItem*,int)</signal>
+ <receiver>LBMLBTRUTransportDialog</receiver>
+ <slot>sourcesDetailItemDoubleClicked(QTreeWidgetItem*,int)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>109</x>
+ <y>344</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>420</x>
+ <y>281</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>sources_detail_ncf_sqn_TreeWidget</sender>
+ <signal>itemDoubleClicked(QTreeWidgetItem*,int)</signal>
+ <receiver>LBMLBTRUTransportDialog</receiver>
+ <slot>sourcesDetailItemDoubleClicked(QTreeWidgetItem*,int)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>83</x>
+ <y>344</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>420</x>
+ <y>281</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>receivers_TreeWidget</sender>
+ <signal>itemClicked(QTreeWidgetItem*,int)</signal>
+ <receiver>LBMLBTRUTransportDialog</receiver>
+ <slot>receiversItemClicked(QTreeWidgetItem*,int)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>420</x>
+ <y>141</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>420</x>
+ <y>281</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>receivers_detail_ComboBox</sender>
+ <signal>currentIndexChanged(int)</signal>
+ <receiver>LBMLBTRUTransportDialog</receiver>
+ <slot>receiversDetailCurrentChanged(int)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>124</x>
+ <y>315</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>155</x>
+ <y>-8</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>receivers_detail_sqn_TreeWidget</sender>
+ <signal>itemDoubleClicked(QTreeWidgetItem*,int)</signal>
+ <receiver>LBMLBTRUTransportDialog</receiver>
+ <slot>receiversDetailItemDoubleClicked(QTreeWidgetItem*,int)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>435</x>
+ <y>452</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>435</x>
+ <y>333</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>receivers_detail_reason_TreeWidget</sender>
+ <signal>itemDoubleClicked(QTreeWidgetItem*,int)</signal>
+ <receiver>LBMLBTRUTransportDialog</receiver>
+ <slot>receiversDetailItemDoubleClicked(QTreeWidgetItem*,int)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>66</x>
+ <y>336</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>435</x>
+ <y>333</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+ <slots>
+ <signal>goToPacket(int)</signal>
+ <slot>sourcesDetailCurrentChanged(int)</slot>
+ <slot>sourcesItemClicked(QTreeWidgetItem*,int)</slot>
+ <slot>receiversItemClicked(QTreeWidgetItem*,int)</slot>
+ <slot>sourcesDetailItemDoubleClicked(QTreeWidgetItem*,int)</slot>
+ <slot>receiversDetailItemDoubleClicked(QTreeWidgetItem*,int)</slot>
+ <slot>receiversDetailCurrentChanged(int)</slot>
+ </slots>
+</ui>
diff --git a/ui/qt/lbm_stream_dialog.cpp b/ui/qt/lbm_stream_dialog.cpp
new file mode 100644
index 0000000000..ceba6fe39a
--- /dev/null
+++ b/ui/qt/lbm_stream_dialog.cpp
@@ -0,0 +1,455 @@
+/* lbm_stream_dialog.cpp
+ *
+ * Copyright (c) 2005-2014 Informatica Corporation. All Rights Reserved.
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+// Adapted from stats_tree_packet.cpp
+
+#include "lbm_stream_dialog.h"
+#include "ui_lbm_stream_dialog.h"
+
+#include "file.h"
+
+#include "wireshark_application.h"
+
+#include <QClipboard>
+#include <QMessageBox>
+#include <QTreeWidget>
+#include <QTreeWidgetItemIterator>
+#include <epan/packet_info.h>
+#include <epan/wmem/wmem.h>
+#include <epan/to_str.h>
+#include <epan/tap.h>
+#include <epan/dissectors/packet-lbm.h>
+
+#include <QDebug>
+
+namespace
+{
+ static const int Stream_Column = 0;
+ static const int EndpointA_Column = 1;
+ static const int EndpointB_Column = 2;
+ static const int Messages_Column = 3;
+ static const int Bytes_Column = 4;
+ static const int FirstFrame_Column = 5;
+ static const int LastFrame_Column = 6;
+}
+
+class LBMSubstreamEntry
+{
+ public:
+ LBMSubstreamEntry(guint64 channel, guint32 substream_id, const address * source_address, guint16 source_port, const address * destination_address, guint16 destination_port);
+ ~LBMSubstreamEntry(void);
+ void processPacket(guint32 frame, guint32 bytes);
+ void setItem(QTreeWidgetItem * item);
+ QTreeWidgetItem * getItem(void)
+ {
+ return (m_item);
+ }
+
+ private:
+ LBMSubstreamEntry(void) { }
+ void fillItem(gboolean update_only = TRUE);
+ guint64 m_channel;
+ guint32 m_substream_id;
+ QString m_endpoint_a;
+ QString m_endpoint_b;
+ guint32 m_first_frame;
+ guint32 m_flast_frame;
+ guint32 m_messages;
+ guint32 m_bytes;
+ QTreeWidgetItem * m_item;
+};
+
+LBMSubstreamEntry::LBMSubstreamEntry(guint64 channel, guint32 substream_id, const address * source_address, guint16 source_port, const address * destination_address, guint16 destination_port) :
+ m_channel(channel),
+ m_substream_id(substream_id),
+ m_first_frame((guint32)(~0)),
+ m_flast_frame(0),
+ m_messages(0),
+ m_bytes(0),
+ m_item(NULL)
+{
+ m_endpoint_a = QString("%1:%2")
+ .arg(address_to_str(wmem_packet_scope(), source_address))
+ .arg(source_port);
+ m_endpoint_b = QString("%1:%2")
+ .arg(address_to_str(wmem_packet_scope(), destination_address))
+ .arg(destination_port);
+}
+
+LBMSubstreamEntry::~LBMSubstreamEntry(void)
+{
+}
+
+void LBMSubstreamEntry::processPacket(guint32 frame, guint32 bytes)
+{
+ if (m_first_frame > frame)
+ {
+ m_first_frame = frame;
+ }
+ if (m_flast_frame < frame)
+ {
+ m_flast_frame = frame;
+ }
+ m_bytes += bytes;
+ m_messages++;
+ fillItem();
+}
+
+void LBMSubstreamEntry::setItem(QTreeWidgetItem * item)
+{
+ m_item = item;
+ fillItem(FALSE);
+}
+
+void LBMSubstreamEntry::fillItem(gboolean update_only)
+{
+ if (update_only == FALSE)
+ {
+ m_item->setText(Stream_Column, QString("%1.%2").arg(m_channel).arg(m_substream_id));
+ m_item->setText(EndpointA_Column, m_endpoint_a);
+ m_item->setText(EndpointB_Column, m_endpoint_b);
+ }
+ m_item->setText(Messages_Column, QString("%1").arg(m_messages));
+ m_item->setText(Bytes_Column, QString("%1").arg(m_bytes));
+ m_item->setText(FirstFrame_Column, QString("%1").arg(m_first_frame));
+ m_item->setText(LastFrame_Column, QString("%1").arg(m_flast_frame));
+}
+
+typedef QMap<guint32, LBMSubstreamEntry *> LBMSubstreamMap;
+typedef QMap<guint32, LBMSubstreamEntry *>::iterator LBMSubstreamMapIterator;
+
+class LBMStreamEntry
+{
+ public:
+ LBMStreamEntry(guint64 channel, const lbm_uim_stream_endpoint_t * endpoint_a, const lbm_uim_stream_endpoint_t * endpoint_b);
+ ~LBMStreamEntry(void);
+ void processPacket(const packet_info * pinfo, const lbm_uim_stream_tap_info_t * stream_info);
+ void setItem(QTreeWidgetItem * item);
+ QTreeWidgetItem * getItem(void)
+ {
+ return (m_item);
+ }
+
+ private:
+ LBMStreamEntry(void) { }
+ void fillItem(gboolean update_only = TRUE);
+ QString formatEndpoint(const lbm_uim_stream_endpoint_t * endpoint);
+ guint64 m_channel;
+ QString m_endpoint_a;
+ QString m_endpoint_b;
+ guint32 m_first_frame;
+ guint32 m_flast_frame;
+ guint32 m_messages;
+ guint32 m_bytes;
+ QTreeWidgetItem * m_item;
+ LBMSubstreamMap m_substreams;
+};
+
+LBMStreamEntry::LBMStreamEntry(guint64 channel, const lbm_uim_stream_endpoint_t * endpoint_a, const lbm_uim_stream_endpoint_t * endpoint_b) :
+ m_channel(channel),
+ m_first_frame((guint32)(~0)),
+ m_flast_frame(0),
+ m_messages(0),
+ m_bytes(0),
+ m_item(NULL),
+ m_substreams()
+{
+ m_endpoint_a = formatEndpoint(endpoint_a);
+ m_endpoint_b = formatEndpoint(endpoint_b);
+}
+
+LBMStreamEntry::~LBMStreamEntry(void)
+{
+ LBMSubstreamMapIterator it;
+
+ for (it = m_substreams.begin(); it != m_substreams.end(); it++)
+ {
+ delete *it;
+ }
+ m_substreams.clear();
+}
+
+QString LBMStreamEntry::formatEndpoint(const lbm_uim_stream_endpoint_t * endpoint)
+{
+ if (endpoint->type == lbm_uim_instance_stream)
+ {
+ return QString(bytes_to_ep_str(endpoint->stream_info.ctxinst.ctxinst, sizeof(endpoint->stream_info.ctxinst.ctxinst)));
+ }
+ else
+ {
+ return QString("%1:%2:%3")
+ .arg(endpoint->stream_info.dest.domain)
+ .arg(address_to_str(wmem_packet_scope(), &(endpoint->stream_info.dest.addr)))
+ .arg(endpoint->stream_info.dest.port);
+ }
+}
+
+void LBMStreamEntry::processPacket(const packet_info * pinfo, const lbm_uim_stream_tap_info_t * stream_info)
+{
+ LBMSubstreamEntry * substream = NULL;
+ LBMSubstreamMapIterator it;
+
+ if (m_first_frame > pinfo->fd->num)
+ {
+ m_first_frame = pinfo->fd->num;
+ }
+ if (m_flast_frame < pinfo->fd->num)
+ {
+ m_flast_frame = pinfo->fd->num;
+ }
+ m_bytes += stream_info->bytes;
+ m_messages++;
+ it = m_substreams.find(stream_info->substream_id);
+ if (m_substreams.end() == it)
+ {
+ QTreeWidgetItem * item = NULL;
+
+ substream = new LBMSubstreamEntry(m_channel, stream_info->substream_id, &(pinfo->src), pinfo->srcport, &(pinfo->dst), pinfo->destport);
+ m_substreams.insert(stream_info->substream_id, substream);
+ item = new QTreeWidgetItem();
+ substream->setItem(item);
+ m_item->addChild(item);
+ m_item->sortChildren(Stream_Column, Qt::AscendingOrder);
+ }
+ else
+ {
+ substream = it.value();
+ }
+ fillItem();
+ substream->processPacket(pinfo->fd->num, stream_info->bytes);
+}
+
+void LBMStreamEntry::setItem(QTreeWidgetItem * item)
+{
+ m_item = item;
+ fillItem(FALSE);
+}
+
+void LBMStreamEntry::fillItem(gboolean update_only)
+{
+ if (update_only == FALSE)
+ {
+ m_item->setData(Stream_Column, Qt::DisplayRole, QVariant((qulonglong)m_channel));
+ m_item->setText(EndpointA_Column, m_endpoint_a);
+ m_item->setText(EndpointB_Column, m_endpoint_b);
+ }
+ m_item->setText(Messages_Column, QString("%1").arg(m_messages));
+ m_item->setText(Bytes_Column, QString("%1").arg(m_bytes));
+ m_item->setText(FirstFrame_Column, QString("%1").arg(m_first_frame));
+ m_item->setText(LastFrame_Column, QString("%1").arg(m_flast_frame));
+}
+
+typedef QMap<guint64, LBMStreamEntry *> LBMStreamMap;
+typedef QMap<guint64, LBMStreamEntry *>::iterator LBMStreamMapIterator;
+
+class LBMStreamDialogInfo
+{
+ public:
+ LBMStreamDialogInfo(void);
+ ~LBMStreamDialogInfo(void);
+ void setDialog(LBMStreamDialog * dialog);
+ LBMStreamDialog * getDialog(void);
+ void processPacket(const packet_info * pinfo, const lbm_uim_stream_tap_info_t * stream_info);
+ void resetStreams(void);
+
+ private:
+ LBMStreamDialog * m_dialog;
+ LBMStreamMap m_streams;
+};
+
+LBMStreamDialogInfo::LBMStreamDialogInfo(void) :
+ m_dialog(NULL),
+ m_streams()
+{
+}
+
+LBMStreamDialogInfo::~LBMStreamDialogInfo(void)
+{
+ resetStreams();
+}
+
+void LBMStreamDialogInfo::setDialog(LBMStreamDialog * dialog)
+{
+ m_dialog = dialog;
+}
+
+LBMStreamDialog * LBMStreamDialogInfo::getDialog(void)
+{
+ return (m_dialog);
+}
+
+void LBMStreamDialogInfo::processPacket(const packet_info * pinfo, const lbm_uim_stream_tap_info_t * stream_info)
+{
+ LBMStreamEntry * stream = NULL;
+ LBMStreamMapIterator it;
+
+ it = m_streams.find(stream_info->channel);
+ if (m_streams.end() == it)
+ {
+ QTreeWidgetItem * item = NULL;
+ QTreeWidgetItem * parent = NULL;
+ Ui::LBMStreamDialog * ui = NULL;
+
+ stream = new LBMStreamEntry(stream_info->channel, &(stream_info->endpoint_a), &(stream_info->endpoint_b));
+ it = m_streams.insert(stream_info->channel, stream);
+ item = new QTreeWidgetItem();
+ stream->setItem(item);
+ ui = m_dialog->getUI();
+ ui->lbm_stream_TreeWidget->addTopLevelItem(item);
+ parent = ui->lbm_stream_TreeWidget->invisibleRootItem();
+ parent->sortChildren(Stream_Column, Qt::AscendingOrder);
+ }
+ else
+ {
+ stream = it.value();
+ }
+ stream->processPacket(pinfo, stream_info);
+}
+
+void LBMStreamDialogInfo::resetStreams(void)
+{
+ LBMStreamMapIterator it = m_streams.begin();
+
+ while (it != m_streams.end())
+ {
+ delete *it;
+ it++;
+ }
+ m_streams.clear();
+}
+
+LBMStreamDialog::LBMStreamDialog(QWidget * parent, capture_file * cfile) :
+ QDialog(parent),
+ m_ui(new Ui::LBMStreamDialog),
+ m_dialog_info(NULL),
+ m_capture_file(cfile)
+{
+ m_ui->setupUi(this);
+ m_dialog_info = new LBMStreamDialogInfo();
+ connect(this, SIGNAL(accepted()), this, SLOT(closeDialog()));
+ connect(this, SIGNAL(rejected()), this, SLOT(closeDialog()));
+ fillTree();
+}
+
+LBMStreamDialog::~LBMStreamDialog(void)
+{
+ delete m_ui;
+ if (m_dialog_info != NULL)
+ {
+ delete m_dialog_info;
+ }
+}
+
+void LBMStreamDialog::setCaptureFile(capture_file * cfile)
+{
+ if (cfile == NULL) // We only want to know when the file closes.
+ {
+ m_capture_file = NULL;
+ m_ui->displayFilterLineEdit->setEnabled(false);
+ m_ui->applyFilterButton->setEnabled(false);
+ }
+}
+
+void LBMStreamDialog::fillTree(void)
+{
+ GString * error_string;
+
+ if (m_capture_file == NULL)
+ {
+ return;
+ }
+ m_dialog_info->setDialog(this);
+
+ error_string = register_tap_listener("lbm_stream",
+ (void *)m_dialog_info,
+ m_ui->displayFilterLineEdit->text().toUtf8().constData(),
+ TL_REQUIRES_COLUMNS,
+ resetTap,
+ tapPacket,
+ drawTreeItems);
+ if (error_string)
+ {
+ QMessageBox::critical(this, tr("LBM Stream failed to attach to tap"),
+ error_string->str);
+ g_string_free(error_string, TRUE);
+ reject();
+ }
+
+ cf_retap_packets(m_capture_file);
+ drawTreeItems(&m_dialog_info);
+ remove_tap_listener((void *)m_dialog_info);
+}
+
+void LBMStreamDialog::resetTap(void * tap_data)
+{
+ LBMStreamDialogInfo * info = (LBMStreamDialogInfo *)tap_data;
+ LBMStreamDialog * dialog = info->getDialog();
+ if (dialog == NULL)
+ {
+ return;
+ }
+ info->resetStreams();
+ dialog->m_ui->lbm_stream_TreeWidget->clear();
+}
+
+gboolean LBMStreamDialog::tapPacket(void * tap_data, packet_info * pinfo, epan_dissect_t * edt, const void * stream_info)
+{
+ Q_UNUSED(edt)
+
+ if (pinfo->fd->flags.passed_dfilter == 1)
+ {
+ const lbm_uim_stream_tap_info_t * tapinfo = (const lbm_uim_stream_tap_info_t *)stream_info;
+ LBMStreamDialogInfo * info = (LBMStreamDialogInfo *)tap_data;
+
+ info->processPacket(pinfo, tapinfo);
+ }
+ return (TRUE);
+}
+
+void LBMStreamDialog::drawTreeItems(void * tap_data)
+{
+ Q_UNUSED(tap_data)
+}
+
+void LBMStreamDialog::on_applyFilterButton_clicked(void)
+{
+ fillTree();
+}
+
+void LBMStreamDialog::closeDialog(void)
+{
+ delete this;
+}
+
+/*
+ * Editor modelines - http://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vi: set shiftwidth=4 tabstop=4 expandtab:
+ * :indentSize=4:tabSize=4:noTabs=true:
+ */
diff --git a/ui/qt/lbm_stream_dialog.h b/ui/qt/lbm_stream_dialog.h
new file mode 100644
index 0000000000..6399c0c7a3
--- /dev/null
+++ b/ui/qt/lbm_stream_dialog.h
@@ -0,0 +1,85 @@
+/* lbm_stream_dialog.h
+ *
+ * Copyright (c) 2005-2014 Informatica Corporation. All Rights Reserved.
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef LBM_STREAM_DIALOG_H
+#define LBM_STREAM_DIALOG_H
+
+#include "config.h"
+
+#include <glib.h>
+
+#include "cfile.h"
+#include <epan/packet_info.h>
+#include <QDialog>
+
+namespace Ui
+{
+ class LBMStreamDialog;
+}
+
+class LBMStreamDialogInfo;
+
+class LBMStreamDialog : public QDialog
+{
+ Q_OBJECT
+
+ public:
+ explicit LBMStreamDialog(QWidget * parent = 0, capture_file * cfile = NULL);
+ ~LBMStreamDialog(void);
+ Ui::LBMStreamDialog * getUI(void)
+ {
+ return (m_ui);
+ }
+
+ public slots:
+ void setCaptureFile(capture_file * cfile);
+
+ private:
+ Ui::LBMStreamDialog * m_ui;
+ LBMStreamDialogInfo * m_dialog_info;
+ capture_file * m_capture_file;
+
+ void fillTree(void);
+ static void resetTap(void * tap_data);
+ static gboolean tapPacket(void * tap_data, packet_info * pinfo, epan_dissect_t * edt, const void * stream_info);
+ static void drawTreeItems(void * tap_data);
+
+ private slots:
+ void closeDialog(void);
+ void on_applyFilterButton_clicked(void);
+};
+
+#endif
+
+/*
+ * Editor modelines - http://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vi: set shiftwidth=4 tabstop=4 expandtab:
+ * :indentSize=4:tabSize=4:noTabs=true:
+ */
diff --git a/ui/qt/lbm_stream_dialog.ui b/ui/qt/lbm_stream_dialog.ui
new file mode 100644
index 0000000000..2f7f16086d
--- /dev/null
+++ b/ui/qt/lbm_stream_dialog.ui
@@ -0,0 +1,159 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>LBMStreamDialog</class>
+ <widget class="QDialog" name="LBMStreamDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>652</width>
+ <height>459</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Dialog</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QTreeWidget" name="lbm_stream_TreeWidget">
+ <column>
+ <property name="text">
+ <string>Stream</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Endpoint A</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Endpoint B</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Messages</string>
+ </property>
+ <property name="textAlignment">
+ <set>AlignLeft|AlignVCenter</set>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Bytes</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>First Frame</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Last Frame</string>
+ </property>
+ </column>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Display filter:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="DisplayFilterEdit" name="displayFilterLineEdit"/>
+ </item>
+ <item>
+ <widget class="QPushButton" name="applyFilterButton">
+ <property name="toolTip">
+ <string>Regenerate statistics using this display filter</string>
+ </property>
+ <property name="text">
+ <string>Apply</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Close|QDialogButtonBox::Help</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ <action name="actionCopyAsCSV">
+ <property name="text">
+ <string>Copy as CSV</string>
+ </property>
+ <property name="toolTip">
+ <string>Copy the tree as CSV</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+C</string>
+ </property>
+ </action>
+ <action name="actionCopyAsYAML">
+ <property name="text">
+ <string>Copy as YAML</string>
+ </property>
+ <property name="toolTip">
+ <string>Copy the tree as YAML</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+Y</string>
+ </property>
+ </action>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>DisplayFilterEdit</class>
+ <extends>QLineEdit</extends>
+ <header location="global">display_filter_edit.h</header>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>LBMStreamDialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>248</x>
+ <y>254</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>157</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>LBMStreamDialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>316</x>
+ <y>260</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>286</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/ui/qt/lbm_uimflow_dialog.cpp b/ui/qt/lbm_uimflow_dialog.cpp
new file mode 100644
index 0000000000..faff6d8a26
--- /dev/null
+++ b/ui/qt/lbm_uimflow_dialog.cpp
@@ -0,0 +1,668 @@
+/* lbm_uimflow_dialog.cpp
+ *
+ * Copyright (c) 2005-2014 Informatica Corporation. All Rights Reserved.
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+// Adapted from sequence_dialog.cpp
+
+#include "lbm_uimflow_dialog.h"
+#include "ui_lbm_uimflow_dialog.h"
+#include <epan/dissectors/packet-lbm.h>
+#include <epan/packet_info.h>
+#include <epan/tap.h>
+#include <epan/to_str.h>
+#include <epan/addr_resolv.h>
+#include <wsutil/nstime.h>
+
+#include "wireshark_application.h"
+
+#include <QDir>
+#include <QFileDialog>
+#include <QFontMetrics>
+#include <QPoint>
+
+#include <QDebug>
+
+static gboolean lbm_uimflow_add_to_graph(seq_analysis_info_t * seq_info, packet_info * pinfo, const lbm_uim_stream_info_t * stream_info)
+{
+ lbm_uim_stream_endpoint_t epa;
+ lbm_uim_stream_endpoint_t epb;
+ seq_analysis_item_t * item;
+ gchar * ctxinst1 = NULL;
+ gchar * ctxinst2 = NULL;
+ gboolean swap_endpoints = FALSE;
+ int rc;
+
+ if (stream_info->endpoint_a.type != stream_info->endpoint_b.type)
+ {
+ return (FALSE);
+ }
+ if (stream_info->endpoint_a.type == lbm_uim_instance_stream)
+ {
+ rc = memcmp((void *)stream_info->endpoint_a.stream_info.ctxinst.ctxinst,
+ (void *)stream_info->endpoint_b.stream_info.ctxinst.ctxinst,
+ LBM_CONTEXT_INSTANCE_BLOCK_SZ);
+ if (rc <= 0)
+ {
+ swap_endpoints = FALSE;
+ }
+ else
+ {
+ swap_endpoints = TRUE;
+ }
+ }
+ else
+ {
+ if (stream_info->endpoint_a.stream_info.dest.domain < stream_info->endpoint_b.stream_info.dest.domain)
+ {
+ swap_endpoints = FALSE;
+ }
+ else if (stream_info->endpoint_a.stream_info.dest.domain > stream_info->endpoint_b.stream_info.dest.domain)
+ {
+ swap_endpoints = TRUE;
+ }
+ else
+ {
+ int compare;
+
+ compare = CMP_ADDRESS(&(stream_info->endpoint_a.stream_info.dest.addr), &(stream_info->endpoint_b.stream_info.dest.addr));
+ if (compare < 0)
+ {
+ swap_endpoints = FALSE;
+ }
+ else if (compare > 0)
+ {
+ swap_endpoints = TRUE;
+ }
+ else
+ {
+ if (stream_info->endpoint_a.stream_info.dest.port <= stream_info->endpoint_b.stream_info.dest.port)
+ {
+ swap_endpoints = FALSE;
+ }
+ else
+ {
+ swap_endpoints = TRUE;
+ }
+ }
+ }
+ }
+ if (swap_endpoints == FALSE)
+ {
+ epa = stream_info->endpoint_a;
+ epb = stream_info->endpoint_b;
+ }
+ else
+ {
+ epb = stream_info->endpoint_a;
+ epa = stream_info->endpoint_b;
+ }
+ item = (seq_analysis_item_t *)g_malloc(sizeof(seq_analysis_item_t));
+ COPY_ADDRESS(&(item->src_addr), &(pinfo->src));
+ COPY_ADDRESS(&(item->dst_addr), &(pinfo->dst));
+ item->fd = pinfo->fd;
+ item->port_src = pinfo->srcport;
+ item->port_dst = pinfo->destport;
+ if (stream_info->description == NULL)
+ {
+ item->frame_label = g_strdup_printf("(%" G_GUINT32_FORMAT ")", stream_info->sqn);
+ }
+ else
+ {
+ item->frame_label = g_strdup_printf("%s (%" G_GUINT32_FORMAT ")", stream_info->description, stream_info->sqn);
+ }
+ if (epa.type == lbm_uim_instance_stream)
+ {
+ ctxinst1 = bytes_to_ep_str(epa.stream_info.ctxinst.ctxinst, sizeof(epa.stream_info.ctxinst.ctxinst));
+ ctxinst2 = bytes_to_ep_str(epb.stream_info.ctxinst.ctxinst, sizeof(epb.stream_info.ctxinst.ctxinst));
+ item->comment = g_strdup_printf("%s <-> %s [%" G_GUINT64_FORMAT "]",
+ ctxinst1,
+ ctxinst2,
+ stream_info->channel);
+ }
+ else
+ {
+ item->comment = g_strdup_printf("%" G_GUINT32_FORMAT ":%s:%" G_GUINT16_FORMAT " <-> %" G_GUINT32_FORMAT ":%s:%" G_GUINT16_FORMAT " [%" G_GUINT64_FORMAT "]",
+ epa.stream_info.dest.domain,
+ address_to_str(wmem_packet_scope(), &(epa.stream_info.dest.addr)),
+ epa.stream_info.dest.port,
+ epb.stream_info.dest.domain,
+ address_to_str(wmem_packet_scope(), &(epb.stream_info.dest.addr)),
+ epb.stream_info.dest.port,
+ stream_info->channel);
+ }
+ item->conv_num = (guint16)LBM_CHANNEL_ID(stream_info->channel);
+ item->display = TRUE;
+ item->line_style = 1;
+ seq_info->list = g_list_prepend(seq_info->list, (gpointer)item);
+ return (TRUE);
+}
+
+static gboolean lbm_uimflow_tap_packet(void * tap_data, packet_info * pinfo, epan_dissect_t * edt _U_, const void * stream_info)
+{
+ Q_UNUSED(edt)
+
+ seq_analysis_info_t * sainfo = (seq_analysis_info_t *)tap_data;
+ const lbm_uim_stream_info_t * info = (const lbm_uim_stream_info_t *)stream_info;
+
+ if ((sainfo->all_packets) || (pinfo->fd->flags.passed_dfilter == 1))
+ {
+ gboolean rc = lbm_uimflow_add_to_graph(sainfo, pinfo, info);
+ return (rc);
+ }
+ return (FALSE);
+}
+
+static void lbm_uimflow_get_analysis(capture_file * cfile, seq_analysis_info_t * seq_info)
+{
+ GList * list = NULL;
+ gchar time_str[COL_MAX_LEN];
+
+ register_tap_listener("lbm_uim", (void *)seq_info, NULL, TL_REQUIRES_COLUMNS, NULL, lbm_uimflow_tap_packet, NULL);
+ cf_retap_packets(cfile);
+ seq_info->list = g_list_reverse(seq_info->list);
+ remove_tap_listener((void *)seq_info);
+
+ /* Fill in the timestamps. */
+ list = g_list_first(seq_info->list);
+ while (list != NULL)
+ {
+ seq_analysis_item_t * seq_item = (seq_analysis_item_t *)list->data;
+ set_fd_time(cfile->epan, seq_item->fd, time_str);
+ seq_item->time_str = g_strdup(time_str);
+ list = g_list_next(list);
+ }
+}
+
+// To do:
+// - Add UTF8 to text dump
+// - Save to XMI? http://www.umlgraph.org/
+// - Time: abs vs delta
+// - Hide nodes
+// - Clickable time + comments?
+// - Incorporate packet comments?
+// - Change line_style to seq_type (i.e. draw ACKs dashed)
+// - Create WSGraph subclasses with common behavior.
+// - Help button and text
+
+LBMUIMFlowDialog::LBMUIMFlowDialog(QWidget * parent, capture_file * cfile) :
+ QDialog(parent),
+ m_ui(new Ui::LBMUIMFlowDialog),
+ m_capture_file(cfile),
+ m_num_items(0),
+ m_packet_num(0),
+ m_node_label_width(20)
+{
+ m_ui->setupUi(this);
+ QCustomPlot * sp = m_ui->sequencePlot;
+
+ m_sequence_diagram = new SequenceDiagram(sp->yAxis, sp->xAxis2, sp->yAxis2);
+ sp->addPlottable(m_sequence_diagram);
+ sp->axisRect()->setRangeDragAxes(sp->xAxis2, sp->yAxis);
+
+ sp->xAxis->setVisible(false);
+ sp->xAxis->setPadding(0);
+ sp->xAxis->setLabelPadding(0);
+ sp->xAxis->setTickLabelPadding(0);
+ sp->xAxis2->setVisible(true);
+ sp->yAxis2->setVisible(true);
+
+ m_one_em = QFontMetrics(sp->yAxis->labelFont()).height();
+ m_ui->horizontalScrollBar->setSingleStep(100 / m_one_em);
+ m_ui->verticalScrollBar->setSingleStep(100 / m_one_em);
+
+ sp->setInteractions(QCP::iRangeDrag);
+
+ m_ui->gridLayout->setSpacing(0);
+ connect(sp->yAxis, SIGNAL(rangeChanged(QCPRange)), sp->yAxis2, SLOT(setRange(QCPRange)));
+
+ m_context_menu.addAction(m_ui->actionReset);
+ m_context_menu.addSeparator();
+ m_context_menu.addAction(m_ui->actionMoveRight10);
+ m_context_menu.addAction(m_ui->actionMoveLeft10);
+ m_context_menu.addAction(m_ui->actionMoveUp10);
+ m_context_menu.addAction(m_ui->actionMoveDown10);
+ m_context_menu.addAction(m_ui->actionMoveRight1);
+ m_context_menu.addAction(m_ui->actionMoveLeft1);
+ m_context_menu.addAction(m_ui->actionMoveUp1);
+ m_context_menu.addAction(m_ui->actionMoveDown1);
+ m_context_menu.addSeparator();
+ m_context_menu.addAction(m_ui->actionGoToPacket);
+
+ memset(&m_sequence_analysis, 0, sizeof(m_sequence_analysis));
+
+ m_ui->showComboBox->blockSignals(true);
+ m_ui->showComboBox->setCurrentIndex(0);
+ m_ui->showComboBox->blockSignals(false);
+ m_sequence_analysis.all_packets = TRUE;
+ m_sequence_analysis.any_addr = TRUE;
+
+ QPushButton * save_bt = m_ui->buttonBox->button(QDialogButtonBox::Save);
+ save_bt->setText(tr("Save As..."));
+
+ // XXX Use recent settings instead
+ if (parent)
+ {
+ resize(parent->width(), parent->height() * 4 / 5);
+ }
+
+ connect(m_ui->horizontalScrollBar, SIGNAL(valueChanged(int)), this, SLOT(hScrollBarChanged(int)));
+ connect(m_ui->verticalScrollBar, SIGNAL(valueChanged(int)), this, SLOT(vScrollBarChanged(int)));
+ connect(sp->xAxis2, SIGNAL(rangeChanged(QCPRange)), this, SLOT(xAxisChanged(QCPRange)));
+ connect(sp->yAxis, SIGNAL(rangeChanged(QCPRange)), this, SLOT(yAxisChanged(QCPRange)));
+ connect(sp, SIGNAL(mousePress(QMouseEvent*)), this, SLOT(diagramClicked(QMouseEvent*)));
+ connect(sp, SIGNAL(mouseMove(QMouseEvent*)), this, SLOT(mouseMoved(QMouseEvent*)));
+ connect(sp, SIGNAL(mouseRelease(QMouseEvent*)), this, SLOT(mouseReleased(QMouseEvent*)));
+ connect(this, SIGNAL(goToPacket(int)), m_sequence_diagram, SLOT(setSelectedPacket(int)));
+
+ disconnect(m_ui->buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
+
+ fillDiagram();
+}
+
+LBMUIMFlowDialog::~LBMUIMFlowDialog(void)
+{
+ delete m_ui;
+}
+
+void LBMUIMFlowDialog::setCaptureFile(capture_file * cfile)
+{
+ if (cfile == NULL) // We only want to know when the file closes.
+ {
+ m_capture_file = NULL;
+ }
+}
+
+void LBMUIMFlowDialog::showEvent(QShowEvent * event)
+{
+ Q_UNUSED(event);
+ resetAxes();
+}
+
+void LBMUIMFlowDialog::resizeEvent(QResizeEvent * event)
+{
+ Q_UNUSED(event);
+ resetAxes(true);
+}
+
+void LBMUIMFlowDialog::keyPressEvent(QKeyEvent * event)
+{
+ int pan_pixels = (event->modifiers() & Qt::ShiftModifier) ? 1 : 10;
+
+ // XXX - Copy some shortcuts from tcp_stream_dialog.cpp
+ switch (event->key())
+ {
+ case Qt::Key_Right:
+ case Qt::Key_L:
+ panAxes(pan_pixels, 0);
+ break;
+ case Qt::Key_Left:
+ case Qt::Key_H:
+ panAxes(-1 * pan_pixels, 0);
+ break;
+ case Qt::Key_Up:
+ case Qt::Key_K:
+ panAxes(0, -1 * pan_pixels);
+ break;
+ case Qt::Key_Down:
+ case Qt::Key_J:
+ panAxes(0, pan_pixels);
+ break;
+ case Qt::Key_0:
+ case Qt::Key_ParenRight: // Shifted 0 on U.S. keyboards
+ case Qt::Key_R:
+ case Qt::Key_Home:
+ resetAxes();
+ break;
+ case Qt::Key_G:
+ on_actionGoToPacket_triggered();
+ break;
+ }
+
+ QDialog::keyPressEvent(event);
+}
+
+void LBMUIMFlowDialog::mouseReleaseEvent(QMouseEvent * event)
+{
+ mouseReleased(event);
+}
+
+void LBMUIMFlowDialog::hScrollBarChanged(int value)
+{
+ if (qAbs(m_ui->sequencePlot->xAxis2->range().center() - value / 100.0) > 0.01)
+ {
+ m_ui->sequencePlot->xAxis2->setRange(value / 100.0, m_ui->sequencePlot->xAxis2->range().size(), Qt::AlignCenter);
+ m_ui->sequencePlot->replot();
+ }
+}
+
+void LBMUIMFlowDialog::vScrollBarChanged(int value)
+{
+ if (qAbs(m_ui->sequencePlot->yAxis->range().center() - value / 100.0) > 0.01)
+ {
+ m_ui->sequencePlot->yAxis->setRange(value / 100.0, m_ui->sequencePlot->yAxis->range().size(), Qt::AlignCenter);
+ m_ui->sequencePlot->replot();
+ }
+}
+
+void LBMUIMFlowDialog::xAxisChanged(QCPRange range)
+{
+ m_ui->horizontalScrollBar->setValue(qRound(range.center() * 100.0));
+ m_ui->horizontalScrollBar->setPageStep(qRound(range.size() * 100.0));
+}
+
+void LBMUIMFlowDialog::yAxisChanged(QCPRange range)
+{
+ m_ui->verticalScrollBar->setValue(qRound(range.center() * 100.0));
+ m_ui->verticalScrollBar->setPageStep(qRound(range.size() * 100.0));
+}
+
+void LBMUIMFlowDialog::diagramClicked(QMouseEvent * event)
+{
+ QCustomPlot * sp = m_ui->sequencePlot;
+
+ if (event->button() == Qt::RightButton)
+ {
+ // XXX We should find some way to get sequenceDiagram to handle a
+ // contextMenuEvent instead.
+ m_context_menu.exec(event->globalPos());
+ }
+ else if (sp->axisRect()->rect().contains(event->pos()))
+ {
+ sp->setCursor(QCursor(Qt::ClosedHandCursor));
+ }
+ on_actionGoToPacket_triggered();
+}
+
+void LBMUIMFlowDialog::mouseMoved(QMouseEvent * event)
+{
+ QCustomPlot * sp = m_ui->sequencePlot;
+ Qt::CursorShape shape = Qt::ArrowCursor;
+ if (event)
+ {
+ if (event->buttons().testFlag(Qt::LeftButton))
+ {
+ shape = Qt::ClosedHandCursor;
+ }
+ else
+ {
+ if (sp->axisRect()->rect().contains(event->pos()))
+ {
+ shape = Qt::OpenHandCursor;
+ }
+ }
+ }
+ sp->setCursor(QCursor(shape));
+
+ m_packet_num = 0;
+ QString hint;
+ if (event)
+ {
+ seq_analysis_item_t * sai = m_sequence_diagram->itemForPosY(event->pos().y());
+ if (sai)
+ {
+ m_packet_num = sai->fd->num;
+ hint = QString("Packet %1: %2").arg(m_packet_num).arg(sai->comment);
+ }
+ }
+
+ if (hint.isEmpty())
+ {
+ hint += tr("%Ln node(s)", "", m_sequence_analysis.num_nodes) + QString(", ")
+ + tr("%Ln item(s)", "", m_num_items);
+ }
+
+ hint.prepend("<small><i>");
+ hint.append("</i></small>");
+ m_ui->hintLabel->setText(hint);
+}
+
+void LBMUIMFlowDialog::mouseReleased(QMouseEvent * event)
+{
+ Q_UNUSED(event);
+ if (m_ui->sequencePlot->cursor().shape() == Qt::ClosedHandCursor)
+ {
+ m_ui->sequencePlot->setCursor(QCursor(Qt::OpenHandCursor));
+ }
+}
+
+void LBMUIMFlowDialog::on_buttonBox_accepted(void)
+{
+ QString file_name, extension;
+ QDir path(wsApp->lastOpenDir());
+ QString pdf_filter = tr("Portable Document Format (*.pdf)");
+ QString png_filter = tr("Portable Network Graphics (*.png)");
+ QString bmp_filter = tr("Windows Bitmap (*.bmp)");
+ // Gaze upon my beautiful graph with lossy artifacts!
+ QString jpeg_filter = tr("JPEG File Interchange Format (*.jpeg *.jpg)");
+ QString ascii_filter = tr("ASCII (*.txt)");
+
+ QString filter = QString("%1;;%2;;%3;;%4")
+ .arg(pdf_filter)
+ .arg(png_filter)
+ .arg(bmp_filter)
+ .arg(jpeg_filter);
+ if (m_capture_file)
+ {
+ filter.append(QString(";;%5").arg(ascii_filter));
+ }
+
+ file_name = QFileDialog::getSaveFileName(this, tr("Wireshark: Save Graph As..."),
+ path.canonicalPath(), filter, &extension);
+
+ if (file_name.length() > 0)
+ {
+ bool save_ok = false;
+ if (extension.compare(pdf_filter) == 0)
+ {
+ save_ok = m_ui->sequencePlot->savePdf(file_name);
+ }
+ else if (extension.compare(png_filter) == 0)
+ {
+ save_ok = m_ui->sequencePlot->savePng(file_name);
+ }
+ else if (extension.compare(bmp_filter) == 0)
+ {
+ save_ok = m_ui->sequencePlot->saveBmp(file_name);
+ }
+ else if (extension.compare(jpeg_filter) == 0)
+ {
+ save_ok = m_ui->sequencePlot->saveJpg(file_name);
+ }
+ else if (extension.compare(ascii_filter) == 0 && m_capture_file)
+ {
+ save_ok = sequence_analysis_dump_to_file(file_name.toUtf8().constData(), &m_sequence_analysis, m_capture_file, 0);
+ }
+ // else error dialog?
+ if (save_ok)
+ {
+ path = QDir(file_name);
+ wsApp->setLastOpenDir(path.canonicalPath().toUtf8().constData());
+ }
+ }
+}
+
+void LBMUIMFlowDialog::fillDiagram(void)
+{
+ QCustomPlot * sp = m_ui->sequencePlot;
+ seq_analysis_info_t new_sa;
+
+ new_sa = m_sequence_analysis;
+ new_sa.list = NULL;
+ new_sa.ht = NULL;
+ new_sa.num_nodes = 0;
+ lbm_uimflow_get_analysis(m_capture_file, &new_sa);
+ m_num_items = sequence_analysis_get_nodes(&new_sa);
+ m_sequence_diagram->setData(&new_sa);
+ sequence_analysis_list_free(&m_sequence_analysis);
+ m_sequence_analysis = new_sa;
+
+ QFontMetrics vfm = QFontMetrics(sp->xAxis2->labelFont());
+ m_node_label_width = 0;
+ for (guint i = 0; i < m_sequence_analysis.num_nodes; i++)
+ {
+ int label_w = vfm.width(ep_address_to_display(&(m_sequence_analysis.nodes[i])));
+ if (m_node_label_width < label_w)
+ {
+ m_node_label_width = label_w;
+ }
+ }
+ m_node_label_width = (m_node_label_width * 3 / 4) + m_one_em;
+
+ mouseMoved(NULL);
+ resetAxes();
+
+ // XXX QCustomPlot doesn't seem to draw any sort of focus indicator.
+ sp->setFocus();
+}
+
+void LBMUIMFlowDialog::panAxes(int x_pixels, int y_pixels)
+{
+ QCustomPlot * sp = m_ui->sequencePlot;
+ double h_pan = 0.0;
+ double v_pan = 0.0;
+
+ h_pan = sp->xAxis2->range().size() * x_pixels / sp->xAxis2->axisRect()->width();
+ v_pan = sp->yAxis->range().size() * y_pixels / sp->yAxis->axisRect()->height();
+ // The GTK+ version won't pan unless we're zoomed. Should we do the same here?
+ if (h_pan)
+ {
+ sp->xAxis2->moveRange(h_pan);
+ sp->replot();
+ }
+ if (v_pan)
+ {
+ sp->yAxis->moveRange(v_pan);
+ sp->replot();
+ }
+}
+
+void LBMUIMFlowDialog::resetAxes(bool keep_lower)
+{
+ QCustomPlot * sp = m_ui->sequencePlot;
+ // Allow space for labels on the top and port numbers on the left.
+ double top_pos = -1.0, left_pos = -0.5;
+ if (keep_lower)
+ {
+ top_pos = sp->yAxis->range().lower;
+ left_pos = sp->xAxis2->range().lower;
+ }
+
+ double range_ratio = sp->xAxis2->axisRect()->width() / m_node_label_width;
+ sp->xAxis2->setRange(left_pos, range_ratio + left_pos);
+
+ range_ratio = sp->yAxis->axisRect()->height() / (m_one_em * 1.5);
+ sp->yAxis->setRange(top_pos, range_ratio + top_pos);
+
+ double rmin = sp->xAxis2->range().size() / 2;
+ m_ui->horizontalScrollBar->setRange((rmin - 0.5) * 100, (m_sequence_analysis.num_nodes - 0.5 - rmin) * 100);
+ xAxisChanged(sp->xAxis2->range());
+
+ rmin = (sp->yAxis->range().size() / 2);
+ m_ui->verticalScrollBar->setRange((rmin - 1.0) * 100, (m_num_items - 0.5 - rmin) * 100);
+ yAxisChanged(sp->yAxis->range());
+
+ sp->replot();
+}
+
+void LBMUIMFlowDialog::on_resetButton_clicked(void)
+{
+ resetAxes();
+}
+
+void LBMUIMFlowDialog::on_actionGoToPacket_triggered(void)
+{
+ if (m_capture_file && m_packet_num > 0)
+ {
+ emit goToPacket(m_packet_num);
+ }
+}
+
+void LBMUIMFlowDialog::on_showComboBox_currentIndexChanged(int index)
+{
+ if (index == 0)
+ {
+ m_sequence_analysis.all_packets = TRUE;
+ }
+ else
+ {
+ m_sequence_analysis.all_packets = FALSE;
+ }
+ fillDiagram();
+}
+
+void LBMUIMFlowDialog::on_actionReset_triggered(void)
+{
+ on_resetButton_clicked();
+}
+
+void LBMUIMFlowDialog::on_actionMoveRight10_triggered(void)
+{
+ panAxes(10, 0);
+}
+
+void LBMUIMFlowDialog::on_actionMoveLeft10_triggered(void)
+{
+ panAxes(-10, 0);
+}
+
+void LBMUIMFlowDialog::on_actionMoveUp10_triggered(void)
+{
+ panAxes(0, -10);
+}
+
+void LBMUIMFlowDialog::on_actionMoveDown10_triggered(void)
+{
+ panAxes(0, 10);
+}
+
+void LBMUIMFlowDialog::on_actionMoveRight1_triggered(void)
+{
+ panAxes(1, 0);
+}
+
+void LBMUIMFlowDialog::on_actionMoveLeft1_triggered(void)
+{
+ panAxes(-1, 0);
+}
+
+void LBMUIMFlowDialog::on_actionMoveUp1_triggered(void)
+{
+ panAxes(0, -1);
+}
+
+void LBMUIMFlowDialog::on_actionMoveDown1_triggered(void)
+{
+ panAxes(0, 1);
+}
+
+/*
+ * Editor modelines - http://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vi: set shiftwidth=4 tabstop=4 expandtab:
+ * :indentSize=4:tabSize=4:noTabs=true:
+ */
diff --git a/ui/qt/lbm_uimflow_dialog.h b/ui/qt/lbm_uimflow_dialog.h
new file mode 100644
index 0000000000..0d37f90de4
--- /dev/null
+++ b/ui/qt/lbm_uimflow_dialog.h
@@ -0,0 +1,117 @@
+/* lbm_uimflow_dialog.h
+ *
+ * Copyright (c) 2005-2014 Informatica Corporation. All Rights Reserved.
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef LBM_UIMFLOW_DIALOG_H
+#define LBM_UIMFLOW_DIALOG_H
+
+#include "config.h"
+
+#include <glib.h>
+
+#include "cfile.h"
+
+#include "epan/packet.h"
+
+#include "sequence_diagram.h"
+
+#include <QDialog>
+#include <QMenu>
+
+namespace Ui
+{
+ class LBMUIMFlowDialog;
+}
+
+class LBMUIMFlowDialog : public QDialog
+{
+ Q_OBJECT
+
+ public:
+ explicit LBMUIMFlowDialog(QWidget * parent = 0, capture_file * cfile = NULL);
+ ~LBMUIMFlowDialog(void);
+
+ signals:
+ void goToPacket(int packet_number);
+
+ public slots:
+ void setCaptureFile(capture_file * CaptureFile);
+
+ protected:
+ void showEvent(QShowEvent * event);
+ void resizeEvent(QResizeEvent * event);
+ void keyPressEvent(QKeyEvent * event);
+ void mouseReleaseEvent(QMouseEvent * event);
+
+ private slots:
+ void hScrollBarChanged(int value);
+ void vScrollBarChanged(int value);
+ void xAxisChanged(QCPRange range);
+ void yAxisChanged(QCPRange range);
+ void diagramClicked(QMouseEvent * event);
+ void mouseMoved(QMouseEvent * event);
+ void mouseReleased(QMouseEvent * event);
+
+ void on_buttonBox_accepted(void);
+ void on_resetButton_clicked(void);
+ void on_actionGoToPacket_triggered(void);
+ void on_showComboBox_currentIndexChanged(int index);
+ void on_actionReset_triggered(void);
+ void on_actionMoveRight10_triggered(void);
+ void on_actionMoveLeft10_triggered(void);
+ void on_actionMoveUp10_triggered(void);
+ void on_actionMoveDown10_triggered(void);
+ void on_actionMoveRight1_triggered(void);
+ void on_actionMoveLeft1_triggered(void);
+ void on_actionMoveUp1_triggered(void);
+ void on_actionMoveDown1_triggered(void);
+
+ private:
+ Ui::LBMUIMFlowDialog * m_ui;
+ SequenceDiagram * m_sequence_diagram;
+ capture_file * m_capture_file;
+ seq_analysis_info_t m_sequence_analysis;
+ int m_num_items;
+ guint32 m_packet_num;
+ double m_one_em;
+ int m_node_label_width;
+ QMenu m_context_menu;
+
+ void fillDiagram(void);
+ void panAxes(int x_pixels, int y_pixels);
+ void resetAxes(bool keep_lower = false);
+};
+
+#endif
+
+/*
+ * Editor modelines - http://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vi: set shiftwidth=4 tabstop=4 expandtab:
+ * :indentSize=4:tabSize=4:noTabs=true:
+ */
diff --git a/ui/qt/lbm_uimflow_dialog.ui b/ui/qt/lbm_uimflow_dialog.ui
new file mode 100644
index 0000000000..3519c4e8b8
--- /dev/null
+++ b/ui/qt/lbm_uimflow_dialog.ui
@@ -0,0 +1,326 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>LBMUIMFlowDialog</class>
+ <widget class="QDialog" name="LBMUIMFlowDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>679</width>
+ <height>568</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>LBM UIM Flows</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="1">
+ <widget class="QScrollBar" name="verticalScrollBar">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QScrollBar" name="horizontalScrollBar">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QFrame" name="frame"/>
+ </item>
+ <item row="0" column="0">
+ <widget class="QCustomPlot" name="sequencePlot" native="true">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>1</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QLabel" name="hintLabel">
+ <property name="toolTip">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;
+
+&lt;h3&gt;Valuable and amazing time-saving keyboard shortcuts&lt;/h3&gt;
+&lt;table&gt;&lt;tbody&gt;
+
+&lt;tr&gt;&lt;th&gt;0&lt;/th&gt;&lt;td&gt;Reset graph to its initial state&lt;/td&gt;&lt;/th&gt;
+
+&lt;tr&gt;&lt;th&gt;→&lt;/th&gt;&lt;td&gt;Move right 10 pixels&lt;/td&gt;&lt;/th&gt;
+&lt;tr&gt;&lt;th&gt;←&lt;/th&gt;&lt;td&gt;Move left 10 pixels&lt;/td&gt;&lt;/th&gt;
+&lt;tr&gt;&lt;th&gt;↑&lt;/th&gt;&lt;td&gt;Move up 10 pixels&lt;/td&gt;&lt;/th&gt;
+&lt;tr&gt;&lt;th&gt;↓&lt;/th&gt;&lt;td&gt;Move down 10 pixels&lt;/td&gt;&lt;/th&gt;
+&lt;tr&gt;&lt;th&gt;&lt;i&gt;Shift+&lt;/i&gt;→&lt;/th&gt;&lt;td&gt;Move right 1 pixel&lt;/td&gt;&lt;/th&gt;
+&lt;tr&gt;&lt;th&gt;&lt;i&gt;Shift+&lt;/i&gt;←&lt;/th&gt;&lt;td&gt;Move left 1 pixel&lt;/td&gt;&lt;/th&gt;
+&lt;tr&gt;&lt;th&gt;&lt;i&gt;Shift+&lt;/i&gt;↑&lt;/th&gt;&lt;td&gt;Move up 1 pixel&lt;/td&gt;&lt;/th&gt;
+&lt;tr&gt;&lt;th&gt;&lt;i&gt;Shift+&lt;/i&gt;↓&lt;/th&gt;&lt;td&gt;Move down 1 pixel&lt;/td&gt;&lt;/th&gt;
+
+&lt;tr&gt;&lt;th&gt;g&lt;/th&gt;&lt;td&gt;Go to packet under cursor&lt;/td&gt;&lt;/th&gt;
+
+&lt;/tbody&gt;&lt;/table&gt;
+&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ <property name="text">
+ <string>&lt;small&gt;&lt;i&gt;A hint&lt;/i&gt;&lt;/small&gt;</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="controlHorizontalLayout" stretch="0,0,1">
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Show:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="showComboBox">
+ <item>
+ <property name="text">
+ <string>All packets</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Displayed packets</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_4">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <spacer name="horizontalSpacer_3">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="resetButton">
+ <property name="text">
+ <string>Reset</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Help|QDialogButtonBox::Ok|QDialogButtonBox::Save</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ <action name="actionReset">
+ <property name="text">
+ <string>Reset Diagram</string>
+ </property>
+ <property name="toolTip">
+ <string>Reset the diagram to its initial state.</string>
+ </property>
+ <property name="shortcut">
+ <string>0</string>
+ </property>
+ </action>
+ <action name="actionMoveUp10">
+ <property name="text">
+ <string>Move Up 10 Pixels</string>
+ </property>
+ <property name="toolTip">
+ <string>Move up 10 pixels</string>
+ </property>
+ <property name="shortcut">
+ <string>Up</string>
+ </property>
+ </action>
+ <action name="actionMoveLeft10">
+ <property name="text">
+ <string>Move Left 10 Pixels</string>
+ </property>
+ <property name="toolTip">
+ <string>Move left 10 pixels</string>
+ </property>
+ <property name="shortcut">
+ <string>Left</string>
+ </property>
+ </action>
+ <action name="actionMoveRight10">
+ <property name="text">
+ <string>Move Right 10 Pixels</string>
+ </property>
+ <property name="toolTip">
+ <string>Move right 10 pixels</string>
+ </property>
+ <property name="shortcut">
+ <string>Right</string>
+ </property>
+ </action>
+ <action name="actionMoveDown10">
+ <property name="text">
+ <string>Move Down 10 Pixels</string>
+ </property>
+ <property name="toolTip">
+ <string>Move down 10 pixels</string>
+ </property>
+ <property name="shortcut">
+ <string>Down</string>
+ </property>
+ </action>
+ <action name="actionMoveUp1">
+ <property name="text">
+ <string>Move Up 1 Pixel</string>
+ </property>
+ <property name="toolTip">
+ <string>Move up 1 pixel</string>
+ </property>
+ <property name="shortcut">
+ <string>Shift+Up</string>
+ </property>
+ </action>
+ <action name="actionMoveLeft1">
+ <property name="text">
+ <string>Move Left 1 Pixel</string>
+ </property>
+ <property name="toolTip">
+ <string>Move left 1 pixel</string>
+ </property>
+ <property name="shortcut">
+ <string>Shift+Left</string>
+ </property>
+ </action>
+ <action name="actionMoveRight1">
+ <property name="text">
+ <string>Move Right 1 Pixel</string>
+ </property>
+ <property name="toolTip">
+ <string>Move right 1 pixel</string>
+ </property>
+ <property name="shortcut">
+ <string>Shift+Right</string>
+ </property>
+ </action>
+ <action name="actionMoveDown1">
+ <property name="text">
+ <string>Move Down 1 Pixel</string>
+ </property>
+ <property name="toolTip">
+ <string>Move down 1 pixel</string>
+ </property>
+ <property name="shortcut">
+ <string>Shift+Down</string>
+ </property>
+ </action>
+ <action name="actionGoToPacket">
+ <property name="text">
+ <string>Go To Packet Under Cursor</string>
+ </property>
+ <property name="toolTip">
+ <string>Go to packet currently under the cursor</string>
+ </property>
+ <property name="shortcut">
+ <string>G</string>
+ </property>
+ </action>
+ <action name="actionFlowAny">
+ <property name="text">
+ <string>All Flows</string>
+ </property>
+ <property name="toolTip">
+ <string>Show flows for all packets</string>
+ </property>
+ <property name="shortcut">
+ <string>1</string>
+ </property>
+ </action>
+ <action name="actionFlowTcp">
+ <property name="text">
+ <string>TCP Flows</string>
+ </property>
+ <property name="toolTip">
+ <string>Show only TCP flow information</string>
+ </property>
+ <property name="shortcut">
+ <string>1</string>
+ </property>
+ </action>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>QCustomPlot</class>
+ <extends>QWidget</extends>
+ <header>qcustomplot.h</header>
+ <container>1</container>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>LBMUIMFlowDialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>248</x>
+ <y>254</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>157</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>LBMUIMFlowDialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>316</x>
+ <y>260</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>286</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/ui/qt/main_window.h b/ui/qt/main_window.h
index 3cc5de5ec3..1ea43582dc 100644
--- a/ui/qt/main_window.h
+++ b/ui/qt/main_window.h
@@ -341,6 +341,21 @@ private slots:
#endif
void openStatisticsTreeDialog(const gchar *abbr);
+ void on_actionStatistics29WestTopics_Advertisements_by_Topic_triggered();
+ void on_actionStatistics29WestTopics_Advertisements_by_Source_triggered();
+ void on_actionStatistics29WestTopics_Advertisements_by_Transport_triggered();
+ void on_actionStatistics29WestTopics_Queries_by_Topic_triggered();
+ void on_actionStatistics29WestTopics_Queries_by_Receiver_triggered();
+ void on_actionStatistics29WestTopics_Wildcard_Queries_by_Pattern_triggered();
+ void on_actionStatistics29WestTopics_Wildcard_Queries_by_Receiver_triggered();
+ void on_actionStatistics29WestQueues_Advertisements_by_Queue_triggered();
+ void on_actionStatistics29WestQueues_Advertisements_by_Source_triggered();
+ void on_actionStatistics29WestQueues_Queries_by_Queue_triggered();
+ void on_actionStatistics29WestQueues_Queries_by_Receiver_triggered();
+ void on_actionStatistics29WestUIM_Streams_triggered();
+ void on_actionStatistics29WestUIM_Stream_Flow_Graph_triggered();
+ void on_actionStatistics29WestLBTRM_triggered();
+ void on_actionStatistics29WestLBTRU_triggered();
void on_actionStatisticsANCP_triggered();
void on_actionStatisticsBACappInstanceId_triggered();
void on_actionStatisticsBACappIP_triggered();
diff --git a/ui/qt/main_window.ui b/ui/qt/main_window.ui
index 0d237c86d6..5407b7bf10 100644
--- a/ui/qt/main_window.ui
+++ b/ui/qt/main_window.ui
@@ -326,12 +326,51 @@
<addaction name="actionStatisticsHTTPRequests"/>
<addaction name="actionStatisticsHTTPLoadDistribution"/>
</widget>
+ <widget class="QMenu" name="menu29West">
+ <property name="title">
+ <string>29West</string>
+ </property>
+ <widget class="QMenu" name="menu29WestTopics">
+ <property name="title">
+ <string>Topics</string>
+ </property>
+ <addaction name="actionStatistics29WestTopics_Advertisements_by_Topic"/>
+ <addaction name="actionStatistics29WestTopics_Advertisements_by_Source"/>
+ <addaction name="actionStatistics29WestTopics_Advertisements_by_Transport"/>
+ <addaction name="actionStatistics29WestTopics_Queries_by_Topic"/>
+ <addaction name="actionStatistics29WestTopics_Queries_by_Receiver"/>
+ <addaction name="actionStatistics29WestTopics_Wildcard_Queries_by_Pattern"/>
+ <addaction name="actionStatistics29WestTopics_Wildcard_Queries_by_Receiver"/>
+ </widget>
+ <widget class="QMenu" name="menu29WestQueues">
+ <property name="title">
+ <string>Queues</string>
+ </property>
+ <addaction name="actionStatistics29WestQueues_Advertisements_by_Queue"/>
+ <addaction name="actionStatistics29WestQueues_Advertisements_by_Source"/>
+ <addaction name="actionStatistics29WestQueues_Queries_by_Queue"/>
+ <addaction name="actionStatistics29WestQueues_Queries_by_Receiver"/>
+ </widget>
+ <widget class="QMenu" name="menu29WestUIM">
+ <property name="title">
+ <string>UIM</string>
+ </property>
+ <addaction name="actionStatistics29WestUIM_Streams"/>
+ <addaction name="actionStatistics29WestUIM_Stream_Flow_Graph"/>
+ </widget>
+ <addaction name="menu29WestTopics"/>
+ <addaction name="menu29WestQueues"/>
+ <addaction name="menu29WestUIM"/>
+ <addaction name="actionStatistics29WestLBTRM"/>
+ <addaction name="actionStatistics29WestLBTRU"/>
+ </widget>
<addaction name="actionSummary"/>
<addaction name="actionProtocol_Hierarchy"/>
<addaction name="actionStatisticsPacketLen"/>
<addaction name="actionStatisticsIOGraph"/>
<addaction name="separator"/>
<addaction name="separator"/>
+ <addaction name="menu29West"/>
<addaction name="actionStatisticsANCP"/>
<addaction name="menuBACnet"/>
<addaction name="actionStatisticsCollectd"/>
@@ -1539,6 +1578,86 @@
<string>Change the way packets are dissected</string>
</property>
</action>
+ <action name="action29West">
+ <property name="text">
+ <string>29West</string>
+ </property>
+ </action>
+ <action name="actionStatistics29WestTopics_Advertisements_by_Topic">
+ <property name="text">
+ <string>Advertisements by Topic</string>
+ </property>
+ </action>
+ <action name="actionStatistics29WestTopics_Advertisements_by_Source">
+ <property name="text">
+ <string>Advertisements by Source</string>
+ </property>
+ </action>
+ <action name="actionStatistics29WestTopics_Advertisements_by_Transport">
+ <property name="text">
+ <string>Advertisements by Transport</string>
+ </property>
+ </action>
+ <action name="actionStatistics29WestTopics_Queries_by_Topic">
+ <property name="text">
+ <string>Queries by Topic</string>
+ </property>
+ </action>
+ <action name="actionStatistics29WestTopics_Queries_by_Receiver">
+ <property name="text">
+ <string>Queries by Receiver</string>
+ </property>
+ </action>
+ <action name="actionStatistics29WestTopics_Wildcard_Queries_by_Pattern">
+ <property name="text">
+ <string>Wildcard Queries by Pattern</string>
+ </property>
+ </action>
+ <action name="actionStatistics29WestTopics_Wildcard_Queries_by_Receiver">
+ <property name="text">
+ <string>Wildcard Queries by Receiver</string>
+ </property>
+ </action>
+ <action name="actionStatistics29WestQueues_Advertisements_by_Queue">
+ <property name="text">
+ <string>Advertisements by Queue</string>
+ </property>
+ </action>
+ <action name="actionStatistics29WestQueues_Advertisements_by_Source">
+ <property name="text">
+ <string>Advertisements by Source</string>
+ </property>
+ </action>
+ <action name="actionStatistics29WestQueues_Queries_by_Queue">
+ <property name="text">
+ <string>Queries by Queue</string>
+ </property>
+ </action>
+ <action name="actionStatistics29WestQueues_Queries_by_Receiver">
+ <property name="text">
+ <string>Queries by Receiver</string>
+ </property>
+ </action>
+ <action name="actionStatistics29WestUIM_Streams">
+ <property name="text">
+ <string>Streams</string>
+ </property>
+ </action>
+ <action name="actionStatistics29WestUIM_Stream_Flow_Graph">
+ <property name="text">
+ <string>Stream Flow Graph</string>
+ </property>
+ </action>
+ <action name="actionStatistics29WestLBTRM">
+ <property name="text">
+ <string>LBT-RM</string>
+ </property>
+ </action>
+ <action name="actionStatistics29WestLBTRU">
+ <property name="text">
+ <string>LBT-RU</string>
+ </property>
+ </action>
<action name="actionSCTPFilterThisAssociation">
<property name="text">
<string>Filter this Association</string>
diff --git a/ui/qt/main_window_slots.cpp b/ui/qt/main_window_slots.cpp
index 4bc3fe2361..7bbb4486d9 100644
--- a/ui/qt/main_window_slots.cpp
+++ b/ui/qt/main_window_slots.cpp
@@ -72,6 +72,10 @@
#include "export_object_dialog.h"
#include "export_pdu_dialog.h"
#include "io_graph_dialog.h"
+#include "lbm_stream_dialog.h"
+#include "lbm_uimflow_dialog.h"
+#include "lbm_lbtrm_transport_dialog.h"
+#include "lbm_lbtru_transport_dialog.h"
#include "packet_comment_dialog.h"
#include "preferences_dialog.h"
#include "print_dialog.h"
@@ -419,7 +423,7 @@ void MainWindow::captureFileReadFinished(const capture_file *cf) {
// add_menu_recent_capture_file(cf->filename);
// /* Remember folder for next Open dialog and save it in recent */
-// dir_path = get_dirname(g_strdup(cf->filename));
+// dir_path = get_dirname(g_strdup(cf->filename));
// wsApp->setLastOpenDir(dir_path);
// g_free(dir_path);
// }
@@ -1911,6 +1915,100 @@ void MainWindow::openStatisticsTreeDialog(const gchar *abbr)
st_dialog->show();
}
+void MainWindow::on_actionStatistics29WestTopics_Advertisements_by_Topic_triggered()
+{
+ openStatisticsTreeDialog("lbmr_topic_ads_topic");
+}
+
+void MainWindow::on_actionStatistics29WestTopics_Advertisements_by_Source_triggered()
+{
+ openStatisticsTreeDialog("lbmr_topic_ads_source");
+}
+
+void MainWindow::on_actionStatistics29WestTopics_Advertisements_by_Transport_triggered()
+{
+ openStatisticsTreeDialog("lbmr_topic_ads_transport");
+}
+
+void MainWindow::on_actionStatistics29WestTopics_Queries_by_Topic_triggered()
+{
+ openStatisticsTreeDialog("lbmr_topic_queries_topic");
+}
+
+void MainWindow::on_actionStatistics29WestTopics_Queries_by_Receiver_triggered()
+{
+ openStatisticsTreeDialog("lbmr_topic_queries_receiver");
+}
+
+void MainWindow::on_actionStatistics29WestTopics_Wildcard_Queries_by_Pattern_triggered()
+{
+ openStatisticsTreeDialog("lbmr_topic_queries_pattern");
+}
+
+void MainWindow::on_actionStatistics29WestTopics_Wildcard_Queries_by_Receiver_triggered()
+{
+ openStatisticsTreeDialog("lbmr_topic_queries_pattern_receiver");
+}
+
+void MainWindow::on_actionStatistics29WestQueues_Advertisements_by_Queue_triggered()
+{
+ openStatisticsTreeDialog("lbmr_queue_ads_queue");
+}
+
+void MainWindow::on_actionStatistics29WestQueues_Advertisements_by_Source_triggered()
+{
+ openStatisticsTreeDialog("lbmr_queue_ads_source");
+}
+
+void MainWindow::on_actionStatistics29WestQueues_Queries_by_Queue_triggered()
+{
+ openStatisticsTreeDialog("lbmr_queue_queries_queue");
+}
+
+void MainWindow::on_actionStatistics29WestQueues_Queries_by_Receiver_triggered()
+{
+ openStatisticsTreeDialog("lbmr_queue_queries_receiver");
+}
+
+void MainWindow::on_actionStatistics29WestUIM_Streams_triggered()
+{
+ LBMStreamDialog *stream_dialog = new LBMStreamDialog(this, cap_file_);
+// connect(stream_dialog, SIGNAL(goToPacket(int)),
+// packet_list_, SLOT(goToPacket(int)));
+ connect(this, SIGNAL(setCaptureFile(capture_file*)),
+ stream_dialog, SLOT(setCaptureFile(capture_file*)));
+ stream_dialog->show();
+}
+
+void MainWindow::on_actionStatistics29WestUIM_Stream_Flow_Graph_triggered()
+{
+ LBMUIMFlowDialog * uimflow_dialog = new LBMUIMFlowDialog(this, cap_file_);
+ connect(uimflow_dialog, SIGNAL(goToPacket(int)),
+ packet_list_, SLOT(goToPacket(int)));
+ connect(this, SIGNAL(setCaptureFile(capture_file*)),
+ uimflow_dialog, SLOT(setCaptureFile(capture_file*)));
+ uimflow_dialog->show();
+}
+
+void MainWindow::on_actionStatistics29WestLBTRM_triggered()
+{
+ LBMLBTRMTransportDialog * lbtrm_dialog = new LBMLBTRMTransportDialog(this, cap_file_);
+ connect(lbtrm_dialog, SIGNAL(goToPacket(int)),
+ packet_list_, SLOT(goToPacket(int)));
+ connect(this, SIGNAL(setCaptureFile(capture_file*)),
+ lbtrm_dialog, SLOT(setCaptureFile(capture_file*)));
+ lbtrm_dialog->show();
+}
+void MainWindow::on_actionStatistics29WestLBTRU_triggered()
+{
+ LBMLBTRUTransportDialog * lbtru_dialog = new LBMLBTRUTransportDialog(this, cap_file_);
+ connect(lbtru_dialog, SIGNAL(goToPacket(int)),
+ packet_list_, SLOT(goToPacket(int)));
+ connect(this, SIGNAL(setCaptureFile(capture_file*)),
+ lbtru_dialog, SLOT(setCaptureFile(capture_file*)));
+ lbtru_dialog->show();
+}
+
void MainWindow::on_actionStatisticsANCP_triggered()
{
openStatisticsTreeDialog("ancp");