diff options
-rw-r--r-- | ui/qt/rtp_analysis_dialog.cpp | 281 | ||||
-rw-r--r-- | ui/qt/rtp_analysis_dialog.h | 15 | ||||
-rw-r--r-- | ui/qt/rtp_player_dialog.h | 2 | ||||
-rw-r--r-- | ui/qt/rtp_stream_dialog.cpp | 150 |
4 files changed, 271 insertions, 177 deletions
diff --git a/ui/qt/rtp_analysis_dialog.cpp b/ui/qt/rtp_analysis_dialog.cpp index caf54d0839..7cb0c9bce9 100644 --- a/ui/qt/rtp_analysis_dialog.cpp +++ b/ui/qt/rtp_analysis_dialog.cpp @@ -242,17 +242,20 @@ enum { num_graphs_ }; -RtpAnalysisDialog::RtpAnalysisDialog(QWidget &parent, CaptureFile &cf) : +RtpAnalysisDialog::RtpAnalysisDialog(QWidget &parent, CaptureFile &cf, struct _rtp_stream_info *stream_fwd, struct _rtp_stream_info *stream_rev) : WiresharkDialog(parent, cf), ui(new Ui::RtpAnalysisDialog), port_src_fwd_(0), port_dst_fwd_(0), ssrc_fwd_(0), - stream_fwd_(0), + packet_count_fwd_(0), + setup_frame_number_fwd_(0), port_src_rev_(0), port_dst_rev_(0), ssrc_rev_(0), - stream_rev_(0) + packet_count_rev_(0), + setup_frame_number_rev_(0), + num_streams_(0) { ui->setupUi(this); setWindowSubtitle(tr("RTP Stream Analysis")); @@ -298,6 +301,8 @@ RtpAnalysisDialog::RtpAnalysisDialog(QWidget &parent, CaptureFile &cf) : memset(&dst_fwd_, 0, sizeof(address)); memset(&src_rev_, 0, sizeof(address)); memset(&dst_rev_, 0, sizeof(address)); + nstime_set_zero(&start_rel_time_fwd_); + nstime_set_zero(&start_rel_time_rev_); QList<QCheckBox *> graph_cbs = QList<QCheckBox *>() << ui->fJitterCheckBox << ui->fDiffCheckBox << ui->fDeltaCheckBox @@ -342,108 +347,39 @@ RtpAnalysisDialog::RtpAnalysisDialog(QWidget &parent, CaptureFile &cf) : save_menu->addAction(ui->actionSaveGraph); ui->buttonBox->button(QDialogButtonBox::Save)->setMenu(save_menu); - const gchar *filter_text = "rtp && rtp.version && rtp.ssrc"; - dfilter_t *sfcode; - gchar *err_msg; - - if (!dfilter_compile(filter_text, &sfcode, &err_msg)) { - QMessageBox::warning(this, tr("No RTP packets found"), QString("%1").arg(err_msg)); - g_free(err_msg); - close(); - } - - if (!cap_file_.capFile() || !cap_file_.capFile()->current_frame) close(); - - frame_data *fdata = cap_file_.capFile()->current_frame; - - if (!cf_read_record(cap_file_.capFile(), fdata)) close(); - - epan_dissect_t edt; - - epan_dissect_init(&edt, cap_file_.capFile()->epan, TRUE, FALSE); - epan_dissect_prime_dfilter(&edt, sfcode); - epan_dissect_run(&edt, cap_file_.capFile()->cd_t, &cap_file_.capFile()->phdr, - frame_tvbuff_new_buffer(fdata, &cap_file_.capFile()->buf), fdata, NULL); - - // This shouldn't happen (the menu item should be disabled) but check anyway - if (!dfilter_apply_edt(sfcode, &edt)) { - epan_dissect_cleanup(&edt); - dfilter_free(sfcode); - err_str_ = tr("Please select an RTP packet"); - updateWidgets(); - return; - } - - dfilter_free(sfcode); - - /* OK, it is an RTP frame. Let's get the IP and port values */ - COPY_ADDRESS(&(src_fwd_), &(edt.pi.src)); - COPY_ADDRESS(&(dst_fwd_), &(edt.pi.dst)); - port_src_fwd_ = edt.pi.srcport; - port_dst_fwd_ = edt.pi.destport; - - /* assume the inverse ip/port combination for the reverse direction */ - COPY_ADDRESS(&(src_rev_), &(edt.pi.dst)); - COPY_ADDRESS(&(dst_rev_), &(edt.pi.src)); - port_src_rev_ = edt.pi.destport; - port_dst_rev_ = edt.pi.srcport; - - /* Check if it is RTP Version 2 */ - unsigned int version_fwd; - bool ok; - version_fwd = getIntFromProtoTree(edt.tree, "rtp", "rtp.version", &ok); - if (!ok || version_fwd != 2) { - err_str_ = tr("RTP version %1 found. Only version 2 is supported.").arg(version_fwd); - updateWidgets(); - return; - } - - /* now we need the SSRC value of the current frame */ - ssrc_fwd_ = getIntFromProtoTree(edt.tree, "rtp", "rtp.ssrc", &ok); - if (!ok) { - err_str_ = tr("SSRC value not found."); - updateWidgets(); - return; - } - - /* Register the tap listener */ - memset(&tapinfo_, 0, sizeof(rtpstream_tapinfo_t)); - tapinfo_.tap_data = this; - tapinfo_.mode = TAP_ANALYSE; - -// register_tap_listener_rtp_stream(&tapinfo_, NULL); - /* Scan for RTP streams (redissect all packets) */ - rtpstream_scan(&tapinfo_, cap_file_.capFile(), NULL); - - num_streams_ = 0; - for (GList *strinfo_list = g_list_first(tapinfo_.strinfo_list); strinfo_list; strinfo_list = g_list_next(strinfo_list)) { - rtp_stream_info_t * strinfo = (rtp_stream_info_t*)(strinfo_list->data); - if (ADDRESSES_EQUAL(&(strinfo->src_addr), &(src_fwd_)) - && (strinfo->src_port == port_src_fwd_) - && (ADDRESSES_EQUAL(&(strinfo->dest_addr), &(dst_fwd_))) - && (strinfo->dest_port == port_dst_fwd_)) - { - ++num_streams_; - stream_fwd_ = strinfo; - } - - if (ADDRESSES_EQUAL(&(strinfo->src_addr), &(src_rev_)) - && (strinfo->src_port == port_src_rev_) - && (ADDRESSES_EQUAL(&(strinfo->dest_addr), &(dst_rev_))) - && (strinfo->dest_port == port_dst_rev_)) - { - ++num_streams_; - if (ssrc_rev_ == 0) { - ssrc_rev_ = strinfo->ssrc; - stream_rev_ = strinfo; - } + if (stream_fwd) { // XXX What if stream_fwd == 0 && stream_rev != 0? + copy_address(&src_fwd_, &(stream_fwd->src_addr)); + port_src_fwd_ = stream_fwd->src_port; + copy_address(&dst_fwd_, &(stream_fwd->dest_addr)); + port_dst_fwd_ = stream_fwd->dest_port; + ssrc_fwd_ = stream_fwd->ssrc; + packet_count_fwd_ = stream_fwd->packet_count; + setup_frame_number_fwd_ = stream_fwd->setup_frame_number; + nstime_copy(&start_rel_time_fwd_, &stream_fwd->start_rel_time); + num_streams_++; + if (stream_rev) { + copy_address(&src_rev_, &(stream_rev->src_addr)); + port_src_rev_ = stream_rev->src_port; + copy_address(&dst_rev_, &(stream_rev->dest_addr)); + port_dst_rev_ = stream_rev->dest_port; + ssrc_rev_ = stream_rev->ssrc; + packet_count_rev_ = stream_rev->packet_count; + setup_frame_number_rev_ = stream_rev->setup_frame_number; + nstime_copy(&start_rel_time_rev_, &stream_rev->start_rel_time); + num_streams_++; } + } else { + findStreams(); } if (num_streams_ < 1) { err_str_ = tr("No streams found."); } + registerTapListener("rtp", this, NULL, 0, tapReset, tapPacket, tapDraw); + cap_file_.retapPackets(); + removeTapListeners(); + connect(ui->tabWidget, SIGNAL(currentChanged(int)), this, SLOT(updateWidgets())); connect(ui->forwardTreeWidget, SIGNAL(itemSelectionChanged()), @@ -454,10 +390,6 @@ RtpAnalysisDialog::RtpAnalysisDialog(QWidget &parent, CaptureFile &cf) : this, SLOT(updateWidgets())); updateWidgets(); - registerTapListener("rtp", this, NULL, 0, tapReset, tapPacket, tapDraw); - cap_file_.retapPackets(); - removeTapListeners(); - updateStatistics(); } @@ -507,7 +439,7 @@ void RtpAnalysisDialog::updateWidgets() ui->actionSaveReverseCsv->setEnabled(enable_save_rev_csv); #if defined(QT_MULTIMEDIA_LIB) - player_button_->setEnabled(stream_fwd_ != 0); + player_button_->setEnabled(num_streams_ > 0); #else player_button_->setEnabled(false); player_button_->setText(tr("No Audio")); @@ -705,18 +637,18 @@ gboolean RtpAnalysisDialog::tapPacket(void *tapinfo_ptr, packet_info *pinfo, epa return FALSE; /* is it the forward direction? */ else if (rtp_analysis_dialog->ssrc_fwd_ == rtpinfo->info_sync_src - && (CMP_ADDRESS(&(rtp_analysis_dialog->src_fwd_), &(pinfo->src)) == 0) + && (cmp_address(&(rtp_analysis_dialog->src_fwd_), &(pinfo->src)) == 0) && (rtp_analysis_dialog->port_src_fwd_ == pinfo->srcport) - && (CMP_ADDRESS(&(rtp_analysis_dialog->dst_fwd_), &(pinfo->dst)) == 0) + && (cmp_address(&(rtp_analysis_dialog->dst_fwd_), &(pinfo->dst)) == 0) && (rtp_analysis_dialog->port_dst_fwd_ == pinfo->destport)) { rtp_analysis_dialog->addPacket(true, pinfo, rtpinfo); } /* is it the reversed direction? */ else if (rtp_analysis_dialog->ssrc_rev_ == rtpinfo->info_sync_src - && (CMP_ADDRESS(&(rtp_analysis_dialog->src_rev_), &(pinfo->src)) == 0) + && (cmp_address(&(rtp_analysis_dialog->src_rev_), &(pinfo->src)) == 0) && (rtp_analysis_dialog->port_src_rev_ == pinfo->srcport) - && (CMP_ADDRESS(&(rtp_analysis_dialog->dst_rev_), &(pinfo->dst)) == 0) + && (cmp_address(&(rtp_analysis_dialog->dst_rev_), &(pinfo->dst)) == 0) && (rtp_analysis_dialog->port_dst_rev_ == pinfo->destport)) { rtp_analysis_dialog->addPacket(false, pinfo, rtpinfo); @@ -1048,12 +980,35 @@ void RtpAnalysisDialog::updateGraph() void RtpAnalysisDialog::showPlayer() { #ifdef QT_MULTIMEDIA_LIB - if (!stream_fwd_) return; + if (num_streams_ < 1) return; RtpPlayerDialog rtp_player_dialog(*this, cap_file_); - - rtp_player_dialog.addRtpStream(stream_fwd_); - if (stream_rev_) rtp_player_dialog.addRtpStream(stream_rev_); + rtp_stream_info_t stream_info; + + // XXX We might want to create an "rtp_stream_id_t" struct with only + // addresses, ports & SSRC. + memset(&stream_info, 0, sizeof(stream_info)); + copy_address(&(stream_info.src_addr), &src_fwd_); + stream_info.src_port = port_src_fwd_; + copy_address(&(stream_info.dest_addr), &dst_fwd_); + stream_info.dest_port = port_dst_fwd_; + stream_info.ssrc = ssrc_fwd_; + stream_info.packet_count = packet_count_fwd_; + stream_info.setup_frame_number = setup_frame_number_fwd_; + nstime_copy(&stream_info.start_rel_time, &start_rel_time_fwd_); + + rtp_player_dialog.addRtpStream(&stream_info); + if (num_streams_ > 1) { + copy_address(&(stream_info.src_addr), &src_rev_); + stream_info.src_port = port_src_rev_; + copy_address(&(stream_info.dest_addr), &dst_rev_); + stream_info.dest_port = port_dst_rev_; + stream_info.ssrc = ssrc_rev_; + stream_info.packet_count = packet_count_rev_; + stream_info.setup_frame_number = setup_frame_number_rev_; + rtp_player_dialog.addRtpStream(&stream_info); + nstime_copy(&stream_info.start_rel_time, &start_rel_time_rev_); + } connect(&rtp_player_dialog, SIGNAL(goToPacket(int)), this, SIGNAL(goToPacket(int))); @@ -1505,6 +1460,110 @@ void RtpAnalysisDialog::graphClicked(QMouseEvent *event) } } +void RtpAnalysisDialog::findStreams() +{ + const gchar *filter_text = "rtp && rtp.version && rtp.ssrc"; + dfilter_t *sfcode; + gchar *err_msg; + + if (!dfilter_compile(filter_text, &sfcode, &err_msg)) { + QMessageBox::warning(this, tr("No RTP packets found"), QString("%1").arg(err_msg)); + g_free(err_msg); + close(); + } + + if (!cap_file_.capFile() || !cap_file_.capFile()->current_frame) close(); + + frame_data *fdata = cap_file_.capFile()->current_frame; + + if (!cf_read_record(cap_file_.capFile(), fdata)) close(); + + epan_dissect_t edt; + + epan_dissect_init(&edt, cap_file_.capFile()->epan, TRUE, FALSE); + epan_dissect_prime_dfilter(&edt, sfcode); + epan_dissect_run(&edt, cap_file_.capFile()->cd_t, &cap_file_.capFile()->phdr, + frame_tvbuff_new_buffer(fdata, &cap_file_.capFile()->buf), fdata, NULL); + + // This shouldn't happen (the menu item should be disabled) but check anyway + if (!dfilter_apply_edt(sfcode, &edt)) { + epan_dissect_cleanup(&edt); + dfilter_free(sfcode); + err_str_ = tr("Please select an RTP packet"); + updateWidgets(); + return; + } + + dfilter_free(sfcode); + + /* OK, it is an RTP frame. Let's get the IP and port values */ + copy_address(&(src_fwd_), &(edt.pi.src)); + copy_address(&(dst_fwd_), &(edt.pi.dst)); + port_src_fwd_ = edt.pi.srcport; + port_dst_fwd_ = edt.pi.destport; + + /* assume the inverse ip/port combination for the reverse direction */ + copy_address(&(src_rev_), &(edt.pi.dst)); + copy_address(&(dst_rev_), &(edt.pi.src)); + port_src_rev_ = edt.pi.destport; + port_dst_rev_ = edt.pi.srcport; + + /* Check if it is RTP Version 2 */ + unsigned int version_fwd; + bool ok; + version_fwd = getIntFromProtoTree(edt.tree, "rtp", "rtp.version", &ok); + if (!ok || version_fwd != 2) { + err_str_ = tr("RTP version %1 found. Only version 2 is supported.").arg(version_fwd); + updateWidgets(); + return; + } + + /* now we need the SSRC value of the current frame */ + ssrc_fwd_ = getIntFromProtoTree(edt.tree, "rtp", "rtp.ssrc", &ok); + if (!ok) { + err_str_ = tr("SSRC value not found."); + updateWidgets(); + return; + } + + /* Register the tap listener */ + memset(&tapinfo_, 0, sizeof(rtpstream_tapinfo_t)); + tapinfo_.tap_data = this; + tapinfo_.mode = TAP_ANALYSE; + +// register_tap_listener_rtp_stream(&tapinfo_, NULL); + /* Scan for RTP streams (redissect all packets) */ + rtpstream_scan(&tapinfo_, cap_file_.capFile(), NULL); + + for (GList *strinfo_list = g_list_first(tapinfo_.strinfo_list); strinfo_list; strinfo_list = g_list_next(strinfo_list)) { + rtp_stream_info_t * strinfo = (rtp_stream_info_t*)(strinfo_list->data); + if (ADDRESSES_EQUAL(&(strinfo->src_addr), &(src_fwd_)) + && (strinfo->src_port == port_src_fwd_) + && (ADDRESSES_EQUAL(&(strinfo->dest_addr), &(dst_fwd_))) + && (strinfo->dest_port == port_dst_fwd_)) + { + packet_count_fwd_ = strinfo->packet_count; + setup_frame_number_fwd_ = strinfo->setup_frame_number; + nstime_copy(&start_rel_time_fwd_, &strinfo->start_rel_time); + num_streams_++; + } + + if (ADDRESSES_EQUAL(&(strinfo->src_addr), &(src_rev_)) + && (strinfo->src_port == port_src_rev_) + && (ADDRESSES_EQUAL(&(strinfo->dest_addr), &(dst_rev_))) + && (strinfo->dest_port == port_dst_rev_)) + { + packet_count_rev_ = strinfo->packet_count; + setup_frame_number_rev_ = strinfo->setup_frame_number; + nstime_copy(&start_rel_time_rev_, &strinfo->start_rel_time); + num_streams_++; + if (ssrc_rev_ == 0) { + ssrc_rev_ = strinfo->ssrc; + } + } + } +} + void RtpAnalysisDialog::showStreamMenu(QPoint pos) { QTreeWidget *cur_tree = qobject_cast<QTreeWidget *>(ui->tabWidget->currentWidget()); diff --git a/ui/qt/rtp_analysis_dialog.h b/ui/qt/rtp_analysis_dialog.h index 68a749ff75..43b3c7a88a 100644 --- a/ui/qt/rtp_analysis_dialog.h +++ b/ui/qt/rtp_analysis_dialog.h @@ -48,7 +48,7 @@ class RtpAnalysisDialog : public WiresharkDialog Q_OBJECT public: - explicit RtpAnalysisDialog(QWidget &parent, CaptureFile &cf); + explicit RtpAnalysisDialog(QWidget &parent, CaptureFile &cf, struct _rtp_stream_info *stream_fwd = 0, struct _rtp_stream_info *stream_rev = 0); ~RtpAnalysisDialog(); signals: @@ -82,19 +82,26 @@ private: Ui::RtpAnalysisDialog *ui; enum StreamDirection { dir_both_, dir_forward_, dir_reverse_ }; + // XXX These are copied to and from rtp_stream_info_t structs. Should + // we just have a pair of those instead? address src_fwd_; guint32 port_src_fwd_; address dst_fwd_; guint32 port_dst_fwd_; guint32 ssrc_fwd_; - struct _rtp_stream_info *stream_fwd_; + guint32 packet_count_fwd_; + guint32 setup_frame_number_fwd_; + nstime_t start_rel_time_fwd_; address src_rev_; guint32 port_src_rev_; address dst_rev_; guint32 port_dst_rev_; guint32 ssrc_rev_; - struct _rtp_stream_info *stream_rev_; + guint32 packet_count_rev_; + guint32 setup_frame_number_rev_; + nstime_t start_rel_time_rev_; + int num_streams_; tap_rtp_stat_t fwd_statinfo_; @@ -123,6 +130,8 @@ private: QMenu stream_ctx_menu_; QMenu graph_ctx_menu_; + void findStreams(); + // Tap callbacks static void tapReset(void *tapinfo_ptr); static gboolean tapPacket(void *tapinfo_ptr, packet_info *pinfo, epan_dissect_t *, const void *rtpinfo_ptr); diff --git a/ui/qt/rtp_player_dialog.h b/ui/qt/rtp_player_dialog.h index 9cb8ed5b9e..01f9039d17 100644 --- a/ui/qt/rtp_player_dialog.h +++ b/ui/qt/rtp_player_dialog.h @@ -63,6 +63,8 @@ public: /** Add an RTP stream to play. * MUST be called before exec(). + * Requires src_addr, src_port, dest_addr, dest_port, ssrc, packet_count, + * setup_frame_number, and start_rel_time. * * @param rtp_stream struct with rtp_stream info */ diff --git a/ui/qt/rtp_stream_dialog.cpp b/ui/qt/rtp_stream_dialog.cpp index 930fac4d83..eebb8db7e2 100644 --- a/ui/qt/rtp_stream_dialog.cpp +++ b/ui/qt/rtp_stream_dialog.cpp @@ -30,6 +30,7 @@ #include <wsutil/utf8_entities.h> #include "qt_ui_utils.h" +#include "rtp_analysis_dialog.h" #include "wireshark_application.h" #include <QAction> @@ -79,42 +80,45 @@ const int max_jitter_col_ = 9; const int mean_jitter_col_ = 10; const int status_col_ = 11; -Q_DECLARE_METATYPE(rtp_stream_info_t*) +enum { rtp_stream_type_ = 1000 }; class RtpStreamTreeWidgetItem : public QTreeWidgetItem { public: - RtpStreamTreeWidgetItem(QTreeWidget *tree, rtp_stream_info_t *stream_info) : QTreeWidgetItem(tree) { - setData(0, Qt::UserRole, qVariantFromValue(stream_info)); + RtpStreamTreeWidgetItem(QTreeWidget *tree, rtp_stream_info_t *stream_info) : + QTreeWidgetItem(tree, rtp_stream_type_), + stream_info_(stream_info) + { drawData(); } + rtp_stream_info_t *streamInfo() const { return stream_info_; } + void drawData() { - rtp_stream_info_t *stream_info = data(0, Qt::UserRole).value<rtp_stream_info_t*>(); - if (!stream_info) { + if (!stream_info_) { return; } - setText(src_addr_col_, address_to_display_qstring(&stream_info->src_addr)); - setText(src_port_col_, QString::number(stream_info->src_port)); - setText(dst_addr_col_, address_to_display_qstring(&stream_info->dest_addr)); - setText(dst_port_col_, QString::number(stream_info->dest_port)); - setText(ssrc_col_, QString("0x%1").arg(stream_info->ssrc, 0, 16)); - - if (stream_info->payload_type_name != NULL) { - setText(payload_col_, stream_info->payload_type_name); + setText(src_addr_col_, address_to_display_qstring(&stream_info_->src_addr)); + setText(src_port_col_, QString::number(stream_info_->src_port)); + setText(dst_addr_col_, address_to_display_qstring(&stream_info_->dest_addr)); + setText(dst_port_col_, QString::number(stream_info_->dest_port)); + setText(ssrc_col_, QString("0x%1").arg(stream_info_->ssrc, 0, 16)); + + if (stream_info_->payload_type_name != NULL) { + setText(payload_col_, stream_info_->payload_type_name); } else { - setText(payload_col_, val_ext_to_qstring(stream_info->payload_type, + setText(payload_col_, val_ext_to_qstring(stream_info_->payload_type, &rtp_payload_type_short_vals_ext, "Unknown (%u)")); } - setText(packets_col_, QString::number(stream_info->packet_count)); + setText(packets_col_, QString::number(stream_info_->packet_count)); guint32 expected; double pct_loss; - expected = (stream_info->rtp_stats.stop_seq_nr + stream_info->rtp_stats.cycles*65536) - - stream_info->rtp_stats.start_seq_nr + 1; - lost_ = expected - stream_info->rtp_stats.total_nr; + expected = (stream_info_->rtp_stats.stop_seq_nr + stream_info_->rtp_stats.cycles*65536) + - stream_info_->rtp_stats.start_seq_nr + 1; + lost_ = expected - stream_info_->rtp_stats.total_nr; if (expected) { pct_loss = (double)(lost_*100.0)/(double)expected; } else { @@ -122,11 +126,11 @@ public: } setText(lost_col_, QObject::tr("%1 (%L2%)").arg(lost_).arg(QString::number(pct_loss, 'f', 1))); - setText(max_delta_col_, QString::number(stream_info->rtp_stats.max_delta, 'f', 3)); // This is RTP. Do we need nanoseconds? - setText(max_jitter_col_, QString::number(stream_info->rtp_stats.max_jitter, 'f', 3)); - setText(mean_jitter_col_, QString::number(stream_info->rtp_stats.mean_jitter, 'f', 3)); + setText(max_delta_col_, QString::number(stream_info_->rtp_stats.max_delta, 'f', 3)); // This is RTP. Do we need nanoseconds? + setText(max_jitter_col_, QString::number(stream_info_->rtp_stats.max_jitter, 'f', 3)); + setText(mean_jitter_col_, QString::number(stream_info_->rtp_stats.mean_jitter, 'f', 3)); - if (stream_info->problem) { + if (stream_info_->problem) { setText(status_col_, UTF8_BULLET); setTextAlignment(status_col_, Qt::AlignCenter); for (int i = 0; i < columnCount(); i++) { @@ -137,8 +141,7 @@ public: } // Return a QString, int, double, or invalid QVariant representing the raw column data. QVariant colData(int col) const { - rtp_stream_info_t *stream_info = data(0, Qt::UserRole).value<rtp_stream_info_t*>(); - if (!stream_info) { + if (!stream_info_) { return QVariant(); } @@ -148,23 +151,23 @@ public: case payload_col_: // XXX Return numeric value? return text(col); case src_port_col_: - return stream_info->src_port; + return stream_info_->src_port; case dst_port_col_: - return stream_info->dest_port; + return stream_info_->dest_port; case ssrc_col_: - return stream_info->ssrc; + return stream_info_->ssrc; case packets_col_: - return stream_info->packet_count; + return stream_info_->packet_count; case lost_col_: return lost_; case max_delta_col_: - return stream_info->rtp_stats.max_delta; + return stream_info_->rtp_stats.max_delta; case max_jitter_col_: - return stream_info->rtp_stats.max_jitter; + return stream_info_->rtp_stats.max_jitter; case mean_jitter_col_: - return stream_info->rtp_stats.mean_jitter; + return stream_info_->rtp_stats.mean_jitter; case status_col_: - return stream_info->problem ? "Problem" : ""; + return stream_info_->problem ? "Problem" : ""; default: break; } @@ -173,36 +176,32 @@ public: bool operator< (const QTreeWidgetItem &other) const { - rtp_stream_info_t *this_stream_info = data(0, Qt::UserRole).value<rtp_stream_info_t*>(); - rtp_stream_info_t *other_stream_info = other.data(0, Qt::UserRole).value<rtp_stream_info_t*>(); - if (!this_stream_info || !other_stream_info) { - return false; - } + if (other.type() != rtp_stream_type_) return QTreeWidgetItem::operator <(other); const RtpStreamTreeWidgetItem &other_rstwi = dynamic_cast<const RtpStreamTreeWidgetItem&>(other); switch (treeWidget()->sortColumn()) { case src_addr_col_: - return cmp_address(&(this_stream_info->src_addr), &(other_stream_info->src_addr)) < 0; + return cmp_address(&(stream_info_->src_addr), &(other_rstwi.stream_info_->src_addr)) < 0; case src_port_col_: - return this_stream_info->src_port < other_stream_info->src_port; + return stream_info_->src_port < other_rstwi.stream_info_->src_port; case dst_addr_col_: - return cmp_address(&(this_stream_info->dest_addr), &(other_stream_info->dest_addr)) < 0; + return cmp_address(&(stream_info_->dest_addr), &(other_rstwi.stream_info_->dest_addr)) < 0; case dst_port_col_: - return this_stream_info->dest_port < other_stream_info->dest_port; + return stream_info_->dest_port < other_rstwi.stream_info_->dest_port; case ssrc_col_: - return this_stream_info->ssrc < other_stream_info->ssrc; + return stream_info_->ssrc < other_rstwi.stream_info_->ssrc; case payload_col_: - return this_stream_info->payload_type < other_stream_info->payload_type; // XXX Compare payload_type_name instead? + return stream_info_->payload_type < other_rstwi.stream_info_->payload_type; // XXX Compare payload_type_name instead? case packets_col_: - return this_stream_info->packet_count < other_stream_info->packet_count; + return stream_info_->packet_count < other_rstwi.stream_info_->packet_count; case lost_col_: return lost_ < other_rstwi.lost_; case max_delta_col_: - return this_stream_info->rtp_stats.max_delta < other_stream_info->rtp_stats.max_delta; + return stream_info_->rtp_stats.max_delta < other_rstwi.stream_info_->rtp_stats.max_delta; case max_jitter_col_: - return this_stream_info->rtp_stats.max_jitter < other_stream_info->rtp_stats.max_jitter; + return stream_info_->rtp_stats.max_jitter < other_rstwi.stream_info_->rtp_stats.max_jitter; case mean_jitter_col_: - return this_stream_info->rtp_stats.mean_jitter < other_stream_info->rtp_stats.mean_jitter; + return stream_info_->rtp_stats.mean_jitter < other_rstwi.stream_info_->rtp_stats.mean_jitter; default: break; } @@ -212,6 +211,7 @@ public: } private: + rtp_stream_info_t *stream_info_; guint32 lost_; }; @@ -387,9 +387,9 @@ void RtpStreamDialog::updateWidgets() if (selected) { int tot_packets = 0; foreach(QTreeWidgetItem *ti, ui->streamTreeWidget->selectedItems()) { - rtp_stream_info_t *stream_info = ti->data(0, Qt::UserRole).value<rtp_stream_info_t *>(); - if (stream_info) { - tot_packets += stream_info->packet_count; + RtpStreamTreeWidgetItem *rsti = static_cast<RtpStreamTreeWidgetItem*>(ti); + if (rsti->streamInfo()) { + tot_packets += rsti->streamInfo()->packet_count; } } hint += tr(", %1 selected, %2 total packets") @@ -408,7 +408,7 @@ void RtpStreamDialog::updateWidgets() prepare_button_->setEnabled(enable); export_button_->setEnabled(enable); copy_button_->setEnabled(has_data); - analyze_button_->setEnabled(false); // XXX No dialog + analyze_button_->setEnabled(selected); ui->actionFindReverse->setEnabled(enable); ui->actionGoToSetup->setEnabled(enable); @@ -417,7 +417,7 @@ void RtpStreamDialog::updateWidgets() ui->actionExportAsRtpDump->setEnabled(enable); ui->actionCopyAsCsv->setEnabled(has_data); ui->actionCopyAsYaml->setEnabled(has_data); - ui->actionAnalyze->setEnabled(false); // XXX No dialog + ui->actionAnalyze->setEnabled(selected); } QList<QVariant> RtpStreamDialog::streamRowData(int row) const @@ -454,7 +454,21 @@ void RtpStreamDialog::showStreamMenu(QPoint pos) void RtpStreamDialog::on_actionAnalyze_triggered() { + rtp_stream_info_t *stream_a, *stream_b = NULL; + + QTreeWidgetItem *ti = ui->streamTreeWidget->selectedItems()[0]; + RtpStreamTreeWidgetItem *rsti = static_cast<RtpStreamTreeWidgetItem*>(ti); + stream_a = rsti->streamInfo(); + if (ui->streamTreeWidget->selectedItems().count() > 1) { + ti = ui->streamTreeWidget->selectedItems()[1]; + rsti = static_cast<RtpStreamTreeWidgetItem*>(ti); + stream_b = rsti->streamInfo(); + } + if (stream_a == NULL && stream_b == NULL) return; + + RtpAnalysisDialog rtp_analysis_dialog(*this, cap_file_, stream_a, stream_b); + rtp_analysis_dialog.exec(); } void RtpStreamDialog::on_actionCopyAsCsv_triggered() @@ -497,7 +511,8 @@ void RtpStreamDialog::on_actionExportAsRtpDump_triggered() // XXX If the user selected multiple frames is this the one we actually want? QTreeWidgetItem *ti = ui->streamTreeWidget->selectedItems()[0]; - rtp_stream_info_t *stream_info = ti->data(0, Qt::UserRole).value<rtp_stream_info_t *>(); + RtpStreamTreeWidgetItem *rsti = static_cast<RtpStreamTreeWidgetItem*>(ti); + rtp_stream_info_t *stream_info = rsti->streamInfo(); if (stream_info) { QString file_name; QDir path(wsApp->lastOpenDir()); @@ -527,7 +542,8 @@ void RtpStreamDialog::on_actionFindReverse_triggered() // Gather up our selected streams... QList<rtp_stream_info_t *> selected_streams; foreach(QTreeWidgetItem *ti, ui->streamTreeWidget->selectedItems()) { - rtp_stream_info_t *stream_info = ti->data(0, Qt::UserRole).value<rtp_stream_info_t *>(); + RtpStreamTreeWidgetItem *rsti = static_cast<RtpStreamTreeWidgetItem*>(ti); + rtp_stream_info_t *stream_info = rsti->streamInfo(); if (stream_info) { selected_streams << stream_info; } @@ -536,10 +552,11 @@ void RtpStreamDialog::on_actionFindReverse_triggered() // ...and compare them to our unselected streams. QTreeWidgetItemIterator iter(ui->streamTreeWidget, QTreeWidgetItemIterator::Unselected); while (*iter) { - rtp_stream_info_t *stream = (*iter)->data(0, Qt::UserRole).value<rtp_stream_info_t*>(); - if (stream) { + RtpStreamTreeWidgetItem *rsti = static_cast<RtpStreamTreeWidgetItem*>(*iter); + rtp_stream_info_t *stream_info = rsti->streamInfo(); + if (stream_info) { foreach (rtp_stream_info_t *fwd_stream, selected_streams) { - if (rtp_stream_info_is_reverse(fwd_stream, stream)) { + if (rtp_stream_info_is_reverse(fwd_stream, stream_info)) { (*iter)->setSelected(true); } } @@ -553,7 +570,8 @@ void RtpStreamDialog::on_actionGoToSetup_triggered() if (ui->streamTreeWidget->selectedItems().count() < 1) return; // XXX If the user selected multiple frames is this the one we actually want? QTreeWidgetItem *ti = ui->streamTreeWidget->selectedItems()[0]; - rtp_stream_info_t *stream_info = ti->data(0, Qt::UserRole).value<rtp_stream_info_t *>(); + RtpStreamTreeWidgetItem *rsti = static_cast<RtpStreamTreeWidgetItem*>(ti); + rtp_stream_info_t *stream_info = rsti->streamInfo(); if (stream_info) { emit goToPacket(stream_info->setup_frame_number); } @@ -564,9 +582,14 @@ void RtpStreamDialog::on_actionMarkPackets_triggered() if (ui->streamTreeWidget->selectedItems().count() < 1) return; rtp_stream_info_t *stream_a, *stream_b = NULL; - stream_a = ui->streamTreeWidget->selectedItems()[0]->data(0, Qt::UserRole).value<rtp_stream_info_t*>(); - if (ui->streamTreeWidget->selectedItems().count() > 1) - stream_b = ui->streamTreeWidget->selectedItems()[1]->data(0, Qt::UserRole).value<rtp_stream_info_t*>(); + QTreeWidgetItem *ti = ui->streamTreeWidget->selectedItems()[0]; + RtpStreamTreeWidgetItem *rsti = static_cast<RtpStreamTreeWidgetItem*>(ti); + stream_a = rsti->streamInfo(); + if (ui->streamTreeWidget->selectedItems().count() > 1) { + ti = ui->streamTreeWidget->selectedItems()[1]; + rsti = static_cast<RtpStreamTreeWidgetItem*>(ti); + stream_b = rsti->streamInfo(); + } if (stream_a == NULL && stream_b == NULL) return; @@ -583,7 +606,8 @@ void RtpStreamDialog::on_actionPrepareFilter_triggered() // Gather up our selected streams... QStringList stream_filters; foreach(QTreeWidgetItem *ti, ui->streamTreeWidget->selectedItems()) { - rtp_stream_info_t *stream_info = ti->data(0, Qt::UserRole).value<rtp_stream_info_t *>(); + RtpStreamTreeWidgetItem *rsti = static_cast<RtpStreamTreeWidgetItem*>(ti); + rtp_stream_info_t *stream_info = rsti->streamInfo(); if (stream_info) { QString ip_proto = stream_info->src_addr.type == AT_IPv6 ? "ipv6" : "ip"; stream_filters << QString("(%1.src==%2 && udp.srcport==%3 && %1.dst==%4 && udp.dstport==%5 && rtp.ssrc==0x%6)") @@ -619,7 +643,7 @@ void RtpStreamDialog::on_buttonBox_clicked(QAbstractButton *button) } else if (button == export_button_) { on_actionExportAsRtpDump_triggered(); } else if (button == analyze_button_) { - + on_actionAnalyze_triggered(); } } |