Qt: Conversation time column updates.

Add a checkbox which lets you toggle between absolute and relative start
times. Use the local time for now. Fixes bug 11618.

Adjust our time precision based on the capture file's time precision.
Fixes bug 12803.

Update the User's Guide accordingly.

Bug: 11618
Bug: 12803
Change-Id: I0049d6db6e4d0b6967bf35e6d056a61bfb4de10f
Reviewed-on: https://code.wireshark.org/review/17448
Petri-Dish: Gerald Combs <gerald@wireshark.org>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Gerald Combs <gerald@wireshark.org>
This commit is contained in:
Gerald Combs 2016-09-01 13:51:13 -07:00
parent df3bf9ca79
commit 5846524f0b
12 changed files with 130 additions and 10 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 245 KiB

After

Width:  |  Height:  |  Size: 235 KiB

View File

@ -141,10 +141,10 @@ description of the known endpoint types can be found in
The conversations window is similar to the endpoint Window. See
<<ChStatEndpointsWindow>> for a description of their common features. Along with
addresses, packet counters, and byte counters the conversation window adds four
columns: the time in seconds between the start of the capture and the start of
the conversation (``Rel Start''), the duration of the conversation in seconds, and
the average bits (not bytes) per second in each direction. A timeline graph is
also drawn across the ``Rel Start'' and ``Duration'' columns.
columns: the start time of the conversation (``Rel Start'') or (``Abs Start''),
the duration of the conversation in seconds, and the average bits (not bytes)
per second in each direction. A timeline graph is also drawn across the
``Rel Start'' / ``Abs Start'' and ``Duration'' columns.
.The ``Conversations'' window
image::wsug_graphics/ws-stats-conversations.png[scaledwidth="100%"]
@ -154,7 +154,10 @@ Each row in the list shows the statistical values for exactly one conversation.
_Name resolution_ will be done if selected in the window and if it is active for
the specific protocol layer (MAC layer for the selected Ethernet endpoints
page). _Limit to display filter_ will only show conversations matching the
current display filter.
current display filter. _Absolute start time_ switches the start time column
between relative (``Rel Start'') and absolute (``Abs Start'') times. Relative start
times match the ``Seconds Since Beginning of Capture'' time display format in the
packet list and absolute start times match the ``Time of Day'' display format.
The button:[Copy] button will copy the list values to the clipboard in CSV
(Comma Separated Values) or YAML format. The button:[Follow Stream...] button

View File

@ -48,7 +48,7 @@ col_format_to_string(const gint fmt) {
"%At", /* 3) COL_ABS_TIME */
"%V", /* 4) COL_VSAN - !! DEPRECATED !!*/
"%B", /* 5) COL_CUMULATIVE_BYTES */
"%Cus", /* 6 COL_CUSTOM */
"%Cus", /* 6) COL_CUSTOM */
"%y", /* 7) COL_DCE_CALL */
"%Tt", /* 8) COL_DELTA_TIME */
"%Gt", /* 9) COL_DELTA_TIME_DIS */

View File

@ -99,6 +99,14 @@ struct _packet_info *CaptureFile::packetInfo()
return NULL;
}
int CaptureFile::timestampPrecision()
{
if (capFile() && capFile()->wth) {
return wtap_file_tsprec(capFile()->wth);
}
return WTAP_TSPREC_UNKNOWN;
}
void CaptureFile::retapPackets()
{
if (cap_file_) {

View File

@ -76,6 +76,12 @@ public:
*/
struct _packet_info *packetInfo();
/** Timestamp precision for the current file.
* @return One of the WTAP_TSPREC_x values defined in wiretap/wtap.h,
* or WTAP_TSPREC_UNKNOWN if no file is open.
*/
int timestampPrecision();
/** Reload the capture file
*/
void reload();

View File

@ -35,6 +35,7 @@
#include "wireshark_application.h"
#include <QCheckBox>
#include <QDateTime>
#include <QDialogButtonBox>
#include <QPushButton>
@ -58,6 +59,9 @@
// Fixed bugs:
// - Friendly unit displays https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=9231
// - Misleading bps calculation https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=8703
// - Show Absolute time in conversation tables https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=11618
// - The value of 'Rel start' and 'Duration' in "Conversations" no need too precise https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=12803
static const QString table_name_ = QObject::tr("Conversation");
ConversationDialog::ConversationDialog(QWidget &parent, CaptureFile &cf, int cli_proto_id, const char *filter) :
@ -71,6 +75,8 @@ ConversationDialog::ConversationDialog(QWidget &parent, CaptureFile &cf, int cli
graph_bt_->setToolTip(tr("Graph a TCP conversation."));
connect(graph_bt_, SIGNAL(clicked()), this, SLOT(graphTcp()));
absoluteTimeCheckBox()->show();
addProgressFrame(&parent);
QList<int> conv_protos;
@ -163,6 +169,9 @@ bool ConversationDialog::addTrafficTable(register_ct_t* table)
this, SIGNAL(filterAction(QString,FilterAction::Action,FilterAction::ActionType)));
connect(nameResolutionCheckBox(), SIGNAL(toggled(bool)),
conv_tree, SLOT(setNameResolutionEnabled(bool)));
connect(absoluteTimeCheckBox(), SIGNAL(toggled(bool)),
conv_tree, SLOT(updateStartTime(bool)));
// XXX Move to ConversationTreeWidget ctor?
QByteArray filter_utf8;
@ -365,9 +374,31 @@ public:
case CONV_COLUMN_BYTES_BA:
return gchar_free_to_qstring(format_size(conv_item->rx_bytes, format_size_unit_none|format_size_prefix_si));
case CONV_COLUMN_START:
return QString::number(nstime_to_sec(&conv_item->start_time), 'f', 9);
{
bool use_ns = treeWidget()->window()->property("nanosecond_precision").toBool();
int width = use_ns ? 9 : 6;
if (treeWidget()->window()->property("absolute_start_time").toBool()) {
nstime_t *abs_time = &conv_item->start_abs_time;
QDateTime abs_dt = QDateTime::fromMSecsSinceEpoch(nstime_to_msec(abs_time));
return QString("%1.%2")
// Mimic column-utils:set_abs_time as best we can
.arg(abs_dt.toString("hh:mm:ss"))
.arg(use_ns ? abs_time->nsecs : abs_time->nsecs / 1000, width, 10, QChar('0'));
}
return QString::number(nstime_to_sec(&conv_item->start_time), 'f', width);
}
case CONV_COLUMN_DURATION:
return QString::number(duration, 'f', 6);
{
// The GTK+ UI uses 9 digit precision for the start time and 4 for the duration.
// Do the same here and above for non-nanosecond precision and add a couple
// of digits for nanosecond precision.
bool use_ns = treeWidget()->window()->property("nanosecond_precision").toBool();
int width = use_ns ? 6 : 4;
return QString::number(duration, 'f', width);
}
case CONV_COLUMN_BPS_AB:
if (duration > min_bw_calc_duration_) {
bps_ab = gchar_free_to_qstring(format_size((gint64) conv_item->tx_bytes * 8 / duration, format_size_unit_none|format_size_prefix_si));
@ -665,6 +696,19 @@ void ConversationTreeWidget::tapDraw(void *conv_hash_ptr)
conv_tree->updateItems();
}
void ConversationTreeWidget::updateStartTime(bool absolute)
{
headerItem()->setText(CONV_COLUMN_START, absolute
? conv_abs_start_title
: conv_column_titles[CONV_COLUMN_START]);
dataChanged(QModelIndex(), QModelIndex());
if (topLevelItemCount() > 0) {
resizeColumnToContents(CONV_COLUMN_START);
}
}
QMap<FilterAction::ActionDirection, conv_direction_e> fad_to_cd_;
void ConversationTreeWidget::initDirectionMap()

View File

@ -38,6 +38,9 @@ public:
double minRelStartTime() { return min_rel_start_time_; }
double maxRelStopTime() { return max_rel_stop_time_; }
public slots:
void updateStartTime(bool absolute);
private:
void initDirectionMap();
void updateItems();

View File

@ -56,12 +56,14 @@ TrafficTableDialog::TrafficTableDialog(QWidget &parent, CaptureFile &cf, const c
ui(new Ui::TrafficTableDialog),
cap_file_(cf),
file_closed_(false),
filter_(filter)
filter_(filter),
nanosecond_timestamps_(false)
{
ui->setupUi(this);
loadGeometry(parent.width(), parent.height() * 3 / 4);
ui->enabledTypesPushButton->setText(tr("%1 Types").arg(table_name));
ui->absoluteTimeCheckBox->hide();
setWindowSubtitle(QString("%1s").arg(table_name));
QMenu *copy_menu = new QMenu();
@ -78,6 +80,10 @@ TrafficTableDialog::TrafficTableDialog(QWidget &parent, CaptureFile &cf, const c
ui->enabledTypesPushButton->setMenu(&traffic_type_menu_);
ui->trafficTableTabWidget->setFocus();
if (cf.timestampPrecision() == WTAP_TSPREC_NSEC) {
nanosecond_timestamps_ = true;
}
connect(wsApp, SIGNAL(addressResolutionChanged()), this, SLOT(currentTabChanged()));
connect(wsApp, SIGNAL(addressResolutionChanged()), this, SLOT(updateWidgets()));
connect(ui->trafficTableTabWidget, SIGNAL(currentChanged(int)),
@ -93,6 +99,11 @@ TrafficTableDialog::~TrafficTableDialog()
delete ui;
}
bool TrafficTableDialog::absoluteStartTime()
{
return absoluteTimeCheckBox()->isChecked();
}
const QList<int> TrafficTableDialog::defaultProtos() const
{
// Reasonable defaults?
@ -144,6 +155,11 @@ QCheckBox *TrafficTableDialog::nameResolutionCheckBox() const
return ui->nameResolutionCheckBox;
}
QCheckBox *TrafficTableDialog::absoluteTimeCheckBox() const
{
return ui->absoluteTimeCheckBox;
}
QPushButton *TrafficTableDialog::enabledTypesPushButton() const
{
return ui->enabledTypesPushButton;

View File

@ -103,6 +103,8 @@ signals:
class TrafficTableDialog : public WiresharkDialog
{
Q_OBJECT
Q_PROPERTY(bool absolute_start_time READ absoluteStartTime)
Q_PROPERTY(bool nanosecond_timestamps READ nanosecondTimestamps)
public:
/** Create a new conversation window.
@ -115,6 +117,16 @@ public:
explicit TrafficTableDialog(QWidget &parent, CaptureFile &cf, const char *filter = NULL, const QString &table_name = tr("Unknown"));
~TrafficTableDialog();
/** Use absolute start times.
* @return true if the "Absolute start time" checkbox is checked, false otherwise.
*/
bool absoluteStartTime();
/** Use nanosecond timestamps.
* @return true if the current capture file uses nanosecond timestamps, false otherwise.
*/
bool nanosecondTimestamps() { return nanosecond_timestamps_; }
public slots:
signals:
@ -143,6 +155,7 @@ protected:
QTabWidget *trafficTableTabWidget() const;
QCheckBox *displayFilterCheckBox() const;
QCheckBox *nameResolutionCheckBox() const;
QCheckBox *absoluteTimeCheckBox() const;
QPushButton *enabledTypesPushButton() const;
protected slots:
@ -151,6 +164,7 @@ protected slots:
private:
QString window_name_;
bool nanosecond_timestamps_;
QList<QVariant> curTreeRowData(int row) const;

View File

@ -15,7 +15,7 @@
<widget class="QTabWidget" name="trafficTableTabWidget"/>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout" stretch="0,0,0,1,0">
<layout class="QHBoxLayout" name="horizontalLayout" stretch="0,0,0,0,0,1,0">
<item>
<widget class="QCheckBox" name="nameResolutionCheckBox">
<property name="toolTip">
@ -49,6 +49,29 @@
</property>
</widget>
</item>
<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="QCheckBox" name="absoluteTimeCheckBox">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Show absolute times in the start time column.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Absolute start time</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
@ -83,6 +106,7 @@
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>

View File

@ -65,6 +65,7 @@ const char *conv_column_titles[CONV_NUM_COLUMNS] = {
const char *conv_conn_a_title = "Connection A";
const char *conv_conn_b_title = "Connection B";
const char *conv_abs_start_title = "Abs Start";
const char *endp_column_titles[ENDP_NUM_COLUMNS] = {
"Address",

View File

@ -54,6 +54,7 @@ typedef enum {
extern const char *conv_column_titles[CONV_NUM_COLUMNS];
extern const char *conv_conn_a_title;
extern const char *conv_conn_b_title;
extern const char *conv_abs_start_title;
typedef enum
{