diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-10 20:34:10 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-10 20:34:10 +0000 |
commit | e4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc (patch) | |
tree | 68cb5ef9081156392f1dd62a00c6ccc1451b93df /ui/qt/response_time_delay_dialog.cpp | |
parent | Initial commit. (diff) | |
download | wireshark-e4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc.tar.xz wireshark-e4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc.zip |
Adding upstream version 4.2.2.upstream/4.2.2
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'ui/qt/response_time_delay_dialog.cpp')
-rw-r--r-- | ui/qt/response_time_delay_dialog.cpp | 270 |
1 files changed, 270 insertions, 0 deletions
diff --git a/ui/qt/response_time_delay_dialog.cpp b/ui/qt/response_time_delay_dialog.cpp new file mode 100644 index 0000000..f656525 --- /dev/null +++ b/ui/qt/response_time_delay_dialog.cpp @@ -0,0 +1,270 @@ +/* response_time_delay_dialog.cpp + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "response_time_delay_dialog.h" + +#include "file.h" + +#include "epan/proto.h" +#include "epan/rtd_table.h" + +#include <QTreeWidget> + +#include <ui/qt/utils/qt_ui_utils.h> +#include "main_application.h" + +static QHash<const QString, register_rtd_t *> cfg_str_to_rtd_; + +extern "C" { +static void +rtd_init(const char *args, void*) { + QStringList args_l = QString(args).split(','); + if (args_l.length() > 1) { + QString rtd = QString("%1,%2").arg(args_l[0]).arg(args_l[1]); + QString filter; + if (args_l.length() > 2) { + filter = QStringList(args_l.mid(2)).join(","); + } + mainApp->emitTapParameterSignal(rtd, filter, NULL); + } +} +} + +bool register_response_time_delay_tables(const void *, void *value, void*) +{ + register_rtd_t *rtd = (register_rtd_t*)value; + const char* short_name = proto_get_protocol_short_name(find_protocol_by_id(get_rtd_proto_id(rtd))); + char *cfg_abbr = rtd_table_get_tap_string(rtd); + + cfg_str_to_rtd_[cfg_abbr] = rtd; + TapParameterDialog::registerDialog( + short_name, + cfg_abbr, + REGISTER_STAT_GROUP_RESPONSE_TIME, + rtd_init, + ResponseTimeDelayDialog::createRtdDialog); + g_free(cfg_abbr); + return FALSE; +} + +enum { + col_type_, + col_messages_, + col_min_srt_, + col_max_srt_, + col_avg_srt_, + col_min_frame_, + col_max_frame_, + col_open_requests, + col_discarded_responses_, + col_repeated_requests_, + col_repeated_responses_ +}; + +enum { + rtd_table_type_ = 1000, + rtd_time_stat_type_ +}; + +class RtdTimeStatTreeWidgetItem : public QTreeWidgetItem +{ +public: + RtdTimeStatTreeWidgetItem(QTreeWidget *parent, const QString type, const rtd_timestat *timestat) : + QTreeWidgetItem (parent, rtd_time_stat_type_), + type_(type), + timestat_(timestat) + { + setText(col_type_, type_); + setHidden(true); + } + void draw() { + setText(col_messages_, QString::number(timestat_->rtd->num)); + setText(col_min_srt_, QString::number(nstime_to_sec(×tat_->rtd->min), 'f', 6)); + setText(col_max_srt_, QString::number(nstime_to_sec(×tat_->rtd->max), 'f', 6)); + setText(col_avg_srt_, QString::number(get_average(×tat_->rtd->tot, timestat_->rtd->num) / 1000.0, 'f', 6)); + setText(col_min_frame_, QString::number(timestat_->rtd->min_num)); + setText(col_max_frame_, QString::number(timestat_->rtd->max_num)); + setText(col_open_requests, QString::number(timestat_->open_req_num)); + setText(col_discarded_responses_, QString::number(timestat_->disc_rsp_num)); + setText(col_repeated_requests_, QString::number(timestat_->req_dup_num)); + setText(col_repeated_responses_, QString::number(timestat_->rsp_dup_num)); + + setHidden(timestat_->rtd->num < 1); + } + bool operator< (const QTreeWidgetItem &other) const + { + if (other.type() != rtd_time_stat_type_) return QTreeWidgetItem::operator< (other); + const RtdTimeStatTreeWidgetItem *other_row = static_cast<const RtdTimeStatTreeWidgetItem *>(&other); + + switch (treeWidget()->sortColumn()) { + case col_messages_: + return timestat_->rtd->num < other_row->timestat_->rtd->num; + case col_min_srt_: + return nstime_cmp(×tat_->rtd->min, &other_row->timestat_->rtd->min) < 0; + case col_max_srt_: + return nstime_cmp(×tat_->rtd->max, &other_row->timestat_->rtd->max) < 0; + case col_avg_srt_: + { + double our_avg = get_average(×tat_->rtd->tot, timestat_->rtd->num); + double other_avg = get_average(&other_row->timestat_->rtd->tot, other_row->timestat_->rtd->num); + return our_avg < other_avg; + } + case col_min_frame_: + return timestat_->rtd->min_num < other_row->timestat_->rtd->min_num; + case col_max_frame_: + return timestat_->rtd->max_num < other_row->timestat_->rtd->max_num; + case col_open_requests: + return timestat_->open_req_num < other_row->timestat_->open_req_num; + case col_discarded_responses_: + return timestat_->disc_rsp_num < other_row->timestat_->disc_rsp_num; + case col_repeated_requests_: + return timestat_->req_dup_num < other_row->timestat_->req_dup_num; + case col_repeated_responses_: + return timestat_->rsp_dup_num < other_row->timestat_->rsp_dup_num; + default: + break; + } + + return QTreeWidgetItem::operator< (other); + } + QList<QVariant> rowData() { + return QList<QVariant>() << type_ << timestat_->rtd->num + << nstime_to_sec(×tat_->rtd->min) << nstime_to_sec(×tat_->rtd->max) + << get_average(×tat_->rtd->tot, timestat_->rtd->num) / 1000.0 + << timestat_->rtd->min_num << timestat_->rtd->max_num + << timestat_->open_req_num << timestat_->disc_rsp_num + << timestat_->req_dup_num << timestat_->rsp_dup_num; + } + +private: + const QString type_; + const rtd_timestat *timestat_; +}; + +ResponseTimeDelayDialog::ResponseTimeDelayDialog(QWidget &parent, CaptureFile &cf, register_rtd *rtd, const QString filter, int help_topic) : + TapParameterDialog(parent, cf, help_topic), + rtd_(rtd) +{ + QString subtitle = tr("%1 Response Time Delay Statistics") + .arg(proto_get_protocol_short_name(find_protocol_by_id(get_rtd_proto_id(rtd)))); + setWindowSubtitle(subtitle); + loadGeometry(0, 0, "ResponseTimeDelayDialog"); + + QStringList header_names = QStringList() + << tr("Type") << tr("Messages") + << tr("Min SRT") << tr("Max SRT") << tr("Avg SRT") + << tr("Min in Frame") << tr("Max in Frame") + << tr("Open Requests") << tr("Discarded Responses") + << tr("Repeated Requests") << tr("Repeated Responses"); + + statsTreeWidget()->setHeaderLabels(header_names); + + for (int col = 0; col < statsTreeWidget()->columnCount(); col++) { + if (col == col_type_) continue; + statsTreeWidget()->headerItem()->setTextAlignment(col, Qt::AlignRight); + } + + if (!filter.isEmpty()) { + setDisplayFilter(filter); + } +} + +TapParameterDialog *ResponseTimeDelayDialog::createRtdDialog(QWidget &parent, const QString cfg_str, const QString filter, CaptureFile &cf) +{ + if (!cfg_str_to_rtd_.contains(cfg_str)) { + // XXX MessageBox? + return NULL; + } + + register_rtd_t *rtd = cfg_str_to_rtd_[cfg_str]; + + return new ResponseTimeDelayDialog(parent, cf, rtd, filter); +} + +void ResponseTimeDelayDialog::addRtdTable(const _rtd_stat_table *rtd_table) +{ + for (unsigned i = 0; i < rtd_table->num_rtds; i++) { + const QString type = val_to_qstring(i, get_rtd_value_string(rtd_), "Other (%d)"); + new RtdTimeStatTreeWidgetItem(statsTreeWidget(), type, &rtd_table->time_stats[i]); + } +} + +void ResponseTimeDelayDialog::tapReset(void *rtdd_ptr) +{ + rtd_data_t *rtdd = (rtd_data_t*) rtdd_ptr; + ResponseTimeDelayDialog *rtd_dlg = static_cast<ResponseTimeDelayDialog *>(rtdd->user_data); + if (!rtd_dlg) return; + + reset_rtd_table(&rtdd->stat_table); + rtd_dlg->statsTreeWidget()->clear(); + rtd_dlg->addRtdTable(&rtdd->stat_table); +} + +void ResponseTimeDelayDialog::tapDraw(void *rtdd_ptr) +{ + rtd_data_t *rtdd = (rtd_data_t*) rtdd_ptr; + ResponseTimeDelayDialog *rtd_dlg = static_cast<ResponseTimeDelayDialog *>(rtdd->user_data); + if (!rtd_dlg || !rtd_dlg->statsTreeWidget()) return; + + QTreeWidgetItemIterator it(rtd_dlg->statsTreeWidget()); + while (*it) { + if ((*it)->type() == rtd_time_stat_type_) { + RtdTimeStatTreeWidgetItem *rtd_ts_ti = static_cast<RtdTimeStatTreeWidgetItem *>((*it)); + rtd_ts_ti->draw(); + } + ++it; + } + + for (int i = 0; i < rtd_dlg->statsTreeWidget()->columnCount() - 1; i++) { + rtd_dlg->statsTreeWidget()->resizeColumnToContents(i); + } +} + +void ResponseTimeDelayDialog::fillTree() +{ + rtd_data_t rtd_data; + memset (&rtd_data, 0, sizeof(rtd_data)); + rtd_table_dissector_init(rtd_, &rtd_data.stat_table, NULL, NULL); + rtd_data.user_data = this; + + QByteArray display_filter = displayFilter().toUtf8(); + if (!registerTapListener(get_rtd_tap_listener_name(rtd_), + &rtd_data, + display_filter.constData(), + 0, + tapReset, + get_rtd_packet_func(rtd_), + tapDraw)) { + free_rtd_table(&rtd_data.stat_table); + reject(); // XXX Stay open instead? + return; + } + + statsTreeWidget()->setSortingEnabled(false); + + cap_file_.retapPackets(); + + tapDraw(&rtd_data); + + statsTreeWidget()->sortItems(col_type_, Qt::AscendingOrder); + statsTreeWidget()->setSortingEnabled(true); + + removeTapListeners(); + free_rtd_table(&rtd_data.stat_table); +} + +QList<QVariant> ResponseTimeDelayDialog::treeItemData(QTreeWidgetItem *ti) const +{ + QList<QVariant> tid; + if (ti->type() == rtd_time_stat_type_) { + RtdTimeStatTreeWidgetItem *rtd_ts_ti = static_cast<RtdTimeStatTreeWidgetItem *>(ti); + tid << rtd_ts_ti->rowData(); + } + return tid; +} |