aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJirka Novak <j.novak@netsystem.cz>2021-03-27 21:01:43 +0100
committerWireshark GitLab Utility <gerald+gitlab-utility@wireshark.org>2021-03-30 07:57:22 +0000
commit47862d8fceffe75acb6db122dc355db084a315c6 (patch)
tree1584541fd8b5ada174055f07dfc311b56de55d3e
parente43058ca592a4bff238126356d38546da2e677b5 (diff)
RTP Player: Dialog is nonmodal now and can be called multiple ways
Changes: - refactored main_dialog handling of telephony dialogs - RTP Player dialog is nonmodal now and can be left open - it is possible to issue three actions on RTP Player dialog from other dialogs (other dialog have selected set of RTP streams before action) - replace - removes existing streams from RTP dialog and shows new set - add - adds new set to existing list in RTP dialog - remove - remove streams in set from list in RTP dialog - Sequence Dialog: - was modified to hold rtpstream_info_t for RTP streams - added Play button - VoIP features (RTP Play button, select/deselect RTP stream) are disabled after creation and must be enabled. It handles that RTP Play button is not shown e.g. in TCP sequence show
-rw-r--r--ui/qt/main_window.h22
-rw-r--r--ui/qt/main_window.ui8
-rw-r--r--ui/qt/main_window_slots.cpp111
-rw-r--r--ui/qt/rtp_analysis_dialog.cpp75
-rw-r--r--ui/qt/rtp_analysis_dialog.h10
-rw-r--r--ui/qt/rtp_audio_stream.cpp11
-rw-r--r--ui/qt/rtp_audio_stream.h1
-rw-r--r--ui/qt/rtp_player_dialog.cpp181
-rw-r--r--ui/qt/rtp_player_dialog.h24
-rw-r--r--ui/qt/rtp_stream_dialog.cpp54
-rw-r--r--ui/qt/rtp_stream_dialog.h8
-rw-r--r--ui/qt/sequence_dialog.cpp81
-rw-r--r--ui/qt/sequence_dialog.h17
-rw-r--r--ui/qt/voip_calls_dialog.cpp67
-rw-r--r--ui/qt/voip_calls_dialog.h15
-rw-r--r--ui/voip_calls.c12
16 files changed, 470 insertions, 227 deletions
diff --git a/ui/qt/main_window.h b/ui/qt/main_window.h
index 91265bad1e..cad88cf6cd 100644
--- a/ui/qt/main_window.h
+++ b/ui/qt/main_window.h
@@ -249,8 +249,7 @@ private:
QPointer<RtpStreamDialog> rtp_stream_dialog_; // Singleton pattern used
QPointer<VoipCallsDialog> voip_calls_dialog_; // Singleton pattern used
QPointer<VoipCallsDialog> sip_calls_dialog_; // Singleton pattern used
-
- void interconnectRtpStreamDialogToTelephonyCallsDialog(RtpStreamDialog *rtp_stream_dialog, VoipCallsDialog *dlg);
+ QPointer<RtpPlayerDialog> rtp_player_dialog_; // Singleton pattern used
void freeze();
void thaw();
@@ -313,6 +312,11 @@ signals:
void framesSelected(QList<int>);
void captureActive(int);
+ void replaceRtpStreams(QVector<rtpstream_info_t *> stream_infos);
+ void addRtpStreams(QVector<rtpstream_info_t *> stream_infos);
+ void removeRtpStreams(QVector<rtpstream_info_t *> stream_infos);
+ void selectRtpStream(rtpstream_id_t *id);
+ void deselectRtpStream(rtpstream_id_t *id);
public slots:
// in main_window_slots.cpp
@@ -360,6 +364,12 @@ public slots:
void on_actionViewFullScreen_triggered(bool checked);
+ void rtpPlayerDialogReplaceRtpStreams(QVector<rtpstream_info_t *> stream_infos);
+ void rtpPlayerDialogAddRtpStreams(QVector<rtpstream_info_t *> stream_infos);
+ void rtpPlayerDialogRemoveRtpStreams(QVector<rtpstream_info_t *> stream_infos);
+ void rtpStreamsDialogSelectRtpStream(rtpstream_id_t *id);
+ void rtpStreamsDialogDeselectRtpStream(rtpstream_id_t *id);
+
private slots:
void captureEventHandler(CaptureEvent ev);
@@ -673,7 +683,9 @@ private slots:
void on_actionStatisticsHpfeeds_triggered();
void on_actionStatisticsHTTP2_triggered();
- void openTelephonyVoipCallsDialog(VoipCallsDialog *dlg);
+ void openTelephonyRtpStreamsDialog();
+ void openTelephonyRtpPlayerDialog();
+ void openTelephonyVoipCallsDialog(bool all_flows);
void on_actionTelephonyVoipCalls_triggered();
void on_actionTelephonyGsmMapSummary_triggered();
void statCommandLteMacStatistics(const char *arg, void *);
@@ -685,8 +697,8 @@ private slots:
void on_actionTelephonyISUPMessages_triggered();
void on_actionTelephonyMtp3Summary_triggered();
void on_actionTelephonyOsmuxPacketCounter_triggered();
- void on_actionTelephonyRTPStreams_triggered();
- void on_actionTelephonyRTPStreamAnalysis_triggered();
+ void on_actionTelephonyRtpStreams_triggered();
+ void on_actionTelephonyRtpStreamAnalysis_triggered();
void on_actionTelephonyRTSPPacketCounter_triggered();
void on_actionTelephonySMPPOperations_triggered();
void on_actionTelephonyUCPMessages_triggered();
diff --git a/ui/qt/main_window.ui b/ui/qt/main_window.ui
index c748efcace..a332421dad 100644
--- a/ui/qt/main_window.ui
+++ b/ui/qt/main_window.ui
@@ -559,8 +559,8 @@
<property name="title">
<string>&amp;RTP</string>
</property>
- <addaction name="actionTelephonyRTPStreams"/>
- <addaction name="actionTelephonyRTPStreamAnalysis"/>
+ <addaction name="actionTelephonyRtpStreams"/>
+ <addaction name="actionTelephonyRtpStreamAnalysis"/>
</widget>
<widget class="QMenu" name="menuTelephonySCTP">
<property name="title">
@@ -2588,7 +2588,7 @@
<string>SIP Flows</string>
</property>
</action>
- <action name="actionTelephonyRTPStreams">
+ <action name="actionTelephonyRtpStreams">
<property name="text">
<string>RTP Streams</string>
</property>
@@ -2842,7 +2842,7 @@
<string notr="true">Ctrl+Space</string>
</property>
</action>
- <action name="actionTelephonyRTPStreamAnalysis">
+ <action name="actionTelephonyRtpStreamAnalysis">
<property name="text">
<string>Stream Analysis</string>
</property>
diff --git a/ui/qt/main_window_slots.cpp b/ui/qt/main_window_slots.cpp
index 71b33967c3..1a08ffb3a0 100644
--- a/ui/qt/main_window_slots.cpp
+++ b/ui/qt/main_window_slots.cpp
@@ -1273,7 +1273,7 @@ void MainWindow::setMenusForSelectedPacket()
main_ui_->actionSCTPAnalyseThisAssociation->setEnabled(is_sctp);
main_ui_->actionSCTPShowAllAssociations->setEnabled(is_sctp);
main_ui_->actionSCTPFilterThisAssociation->setEnabled(is_sctp);
- main_ui_->actionTelephonyRTPStreamAnalysis->setEnabled(is_rtp);
+ main_ui_->actionTelephonyRtpStreamAnalysis->setEnabled(is_rtp);
main_ui_->actionTelephonyLteRlcGraph->setEnabled(is_lte_rlc);
}
@@ -3304,36 +3304,56 @@ void MainWindow::on_actionStatisticsHTTP2_triggered()
// Telephony Menu
-void MainWindow::interconnectRtpStreamDialogToTelephonyCallsDialog(RtpStreamDialog *rtp_stream_dialog, VoipCallsDialog *dlg)
+void MainWindow::openTelephonyRtpPlayerDialog()
{
- if (rtp_stream_dialog && dlg) {
- // Connect signals between dialogs
- connect(dlg, SIGNAL(selectRtpStreamPassOut(rtpstream_id_t *)), rtp_stream_dialog, SLOT(selectRtpStream(rtpstream_id_t *)));
- connect(dlg, SIGNAL(deselectRtpStreamPassOut(rtpstream_id_t *)), rtp_stream_dialog, SLOT(deselectRtpStream(rtpstream_id_t *)));
+ if (!rtp_player_dialog_) {
+ rtp_player_dialog_ = new RtpPlayerDialog(*this, capture_file_);
}
+
+ connect(rtp_player_dialog_, SIGNAL(goToPacket(int)),
+ packet_list_, SLOT(goToPacket(int)));
+ connect(this, SIGNAL(replaceRtpStreams(QVector<rtpstream_info_t *>)),
+ rtp_player_dialog_, SLOT(replaceRtpStreams(QVector<rtpstream_info_t *>)));
+ connect(this, SIGNAL(addRtpStreams(QVector<rtpstream_info_t *>)),
+ rtp_player_dialog_, SLOT(addRtpStreams(QVector<rtpstream_info_t *>)));
+ connect(this, SIGNAL(removeRtpStreams(QVector<rtpstream_info_t *>)),
+ rtp_player_dialog_, SLOT(removeRtpStreams(QVector<rtpstream_info_t *>)));
+ rtp_player_dialog_->show();
}
-void MainWindow::openTelephonyVoipCallsDialog(VoipCallsDialog *dlg)
+void MainWindow::openTelephonyVoipCallsDialog(bool all_flows)
{
+ VoipCallsDialog *dlg;
+
+ if (all_flows) {
+ if (!sip_calls_dialog_) {
+ sip_calls_dialog_ = new VoipCallsDialog(*this, capture_file_, true);
+ }
+ dlg = sip_calls_dialog_;
+ } else {
+ if (!voip_calls_dialog_) {
+ voip_calls_dialog_ = new VoipCallsDialog(*this, capture_file_, false);
+ }
+ dlg = voip_calls_dialog_;
+ }
connect(dlg, SIGNAL(goToPacket(int)),
packet_list_, SLOT(goToPacket(int)));
connect(dlg, SIGNAL(updateFilter(QString, bool)),
this, SLOT(filterPackets(QString, bool)));
- connect(dlg, SIGNAL(openRtpStreamDialogPassOut()),
- this, SLOT(on_actionTelephonyRTPStreams_triggered()));
connect(this, SIGNAL(displayFilterSuccess(bool)),
dlg, SLOT(displayFilterSuccess(bool)));
- interconnectRtpStreamDialogToTelephonyCallsDialog(rtp_stream_dialog_, dlg);
+ connect(dlg, SIGNAL(rtpPlayerDialogReplaceRtpStreams(QVector<rtpstream_info_t *>)),
+ this, SLOT(rtpPlayerDialogReplaceRtpStreams(QVector<rtpstream_info_t *>)));
+ connect(dlg, SIGNAL(rtpPlayerDialogAddRtpStreams(QVector<rtpstream_info_t *>)),
+ this, SLOT(rtpPlayerDialogAddRtpStreams(QVector<rtpstream_info_t *>)));
+ connect(dlg, SIGNAL(rtpPlayerDialogRemoveRtpStreams(QVector<rtpstream_info_t *>)),
+ this, SLOT(rtpPlayerDialogRemoveRtpStreams(QVector<rtpstream_info_t *>)));
dlg->show();
- dlg->raise();
}
void MainWindow::on_actionTelephonyVoipCalls_triggered()
{
- if (!voip_calls_dialog_) {
- voip_calls_dialog_ = new VoipCallsDialog(*this, capture_file_, false);
- }
- openTelephonyVoipCallsDialog(voip_calls_dialog_);
+ openTelephonyVoipCallsDialog(false);
}
void MainWindow::on_actionTelephonyGsmMapSummary_triggered()
@@ -3418,7 +3438,7 @@ void MainWindow::on_actionTelephonyOsmuxPacketCounter_triggered()
openStatisticsTreeDialog("osmux");
}
-void MainWindow::on_actionTelephonyRTPStreams_triggered()
+void MainWindow::openTelephonyRtpStreamsDialog()
{
if (!rtp_stream_dialog_) {
rtp_stream_dialog_ = new RtpStreamDialog(*this, capture_file_);
@@ -3431,17 +3451,33 @@ void MainWindow::on_actionTelephonyRTPStreams_triggered()
this, SLOT(filterPackets(QString, bool)));
connect(this, SIGNAL(displayFilterSuccess(bool)),
rtp_stream_dialog_, SLOT(displayFilterSuccess(bool)));
- interconnectRtpStreamDialogToTelephonyCallsDialog(rtp_stream_dialog_, voip_calls_dialog_);
- interconnectRtpStreamDialogToTelephonyCallsDialog(rtp_stream_dialog_, sip_calls_dialog_);
+ connect(rtp_stream_dialog_, SIGNAL(rtpPlayerDialogReplaceRtpStreams(QVector<rtpstream_info_t *>)),
+ this, SLOT(rtpPlayerDialogReplaceRtpStreams(QVector<rtpstream_info_t *>)));
+ connect(rtp_stream_dialog_, SIGNAL(rtpPlayerDialogAddRtpStreams(QVector<rtpstream_info_t *>)),
+ this, SLOT(rtpPlayerDialogAddRtpStreams(QVector<rtpstream_info_t *>)));
+ connect(rtp_stream_dialog_, SIGNAL(rtpPlayerDialogRemoveRtpStreams(QVector<rtpstream_info_t *>)),
+ this, SLOT(rtpPlayerDialogRemoveRtpStreams(QVector<rtpstream_info_t *>)));
+ connect(this, SIGNAL(selectRtpStream(rtpstream_id_t *)), rtp_stream_dialog_, SLOT(selectRtpStream(rtpstream_id_t *)));
+ connect(this, SIGNAL(deselectRtpStream(rtpstream_id_t *)), rtp_stream_dialog_, SLOT(deselectRtpStream(rtpstream_id_t *)));
rtp_stream_dialog_->show();
- rtp_stream_dialog_->raise();
}
-void MainWindow::on_actionTelephonyRTPStreamAnalysis_triggered()
+void MainWindow::on_actionTelephonyRtpStreams_triggered()
+{
+ openTelephonyRtpStreamsDialog();
+}
+
+void MainWindow::on_actionTelephonyRtpStreamAnalysis_triggered()
{
RtpAnalysisDialog *rtp_analysis_dialog = new RtpAnalysisDialog(*this, capture_file_);
connect(rtp_analysis_dialog, SIGNAL(goToPacket(int)),
packet_list_, SLOT(goToPacket(int)));
+ connect(rtp_analysis_dialog, SIGNAL(rtpPlayerDialogReplaceRtpStreams(QVector<rtpstream_info_t *>)),
+ this, SLOT(rtpPlayerDialogReplaceRtpStreams(QVector<rtpstream_info_t *>)));
+ connect(rtp_analysis_dialog, SIGNAL(rtpPlayerDialogAddRtpStreams(QVector<rtpstream_info_t *>)),
+ this, SLOT(rtpPlayerDialogAddRtpStreams(QVector<rtpstream_info_t *>)));
+ connect(rtp_analysis_dialog, SIGNAL(rtpPlayerDialogRemoveRtpStreams(QVector<rtpstream_info_t *>)),
+ this, SLOT(rtpPlayerDialogRemoveRtpStreams(QVector<rtpstream_info_t *>)));
rtp_analysis_dialog->show();
}
@@ -3462,10 +3498,7 @@ void MainWindow::on_actionTelephonyUCPMessages_triggered()
void MainWindow::on_actionTelephonySipFlows_triggered()
{
- if (!sip_calls_dialog_) {
- sip_calls_dialog_ = new VoipCallsDialog(*this, capture_file_, true);
- }
- openTelephonyVoipCallsDialog(sip_calls_dialog_);
+ openTelephonyVoipCallsDialog(true);
}
// Wireless Menu
@@ -4019,6 +4052,36 @@ void MainWindow::activatePluginIFToolbar(bool)
}
}
+void MainWindow::rtpPlayerDialogReplaceRtpStreams(QVector<rtpstream_info_t *> stream_infos)
+{
+ openTelephonyRtpPlayerDialog();
+ emit replaceRtpStreams(stream_infos);
+}
+
+void MainWindow::rtpPlayerDialogAddRtpStreams(QVector<rtpstream_info_t *> stream_infos)
+{
+ openTelephonyRtpPlayerDialog();
+ emit addRtpStreams(stream_infos);
+}
+
+void MainWindow::rtpPlayerDialogRemoveRtpStreams(QVector<rtpstream_info_t *> stream_infos)
+{
+ openTelephonyRtpPlayerDialog();
+ emit removeRtpStreams(stream_infos);
+}
+
+void MainWindow::rtpStreamsDialogSelectRtpStream(rtpstream_id_t *id)
+{
+ openTelephonyRtpStreamsDialog();
+ emit selectRtpStream(id);
+}
+
+void MainWindow::rtpStreamsDialogDeselectRtpStream(rtpstream_id_t *id)
+{
+ openTelephonyRtpStreamsDialog();
+ emit deselectRtpStream(id);
+}
+
#ifdef _MSC_VER
#pragma warning(pop)
#endif
diff --git a/ui/qt/rtp_analysis_dialog.cpp b/ui/qt/rtp_analysis_dialog.cpp
index d640f90a36..7951f4a74c 100644
--- a/ui/qt/rtp_analysis_dialog.cpp
+++ b/ui/qt/rtp_analysis_dialog.cpp
@@ -328,7 +328,7 @@ RtpAnalysisDialog::RtpAnalysisDialog(QWidget &parent, CaptureFile &cf, rtpstream
ui->actionSaveReverseAudioSyncFile->setEnabled(false);
}
- player_button_ = RtpPlayerDialog::addPlayerButton(ui->buttonBox);
+ player_button_ = RtpPlayerDialog::addPlayerButton(ui->buttonBox, this);
QPushButton *export_btn = ui->buttonBox->addButton(ui->actionExportButton->text(), QDialogButtonBox::ActionRole);
export_btn->setToolTip(ui->actionExportButton->toolTip());
@@ -442,9 +442,6 @@ void RtpAnalysisDialog::updateWidgets()
#if defined(QT_MULTIMEDIA_LIB)
player_button_->setEnabled(num_streams_ > 0 && !file_closed_);
-#else
- player_button_->setEnabled(false);
- player_button_->setText(tr("No Audio"));
#endif
ui->tabWidget->setEnabled(enable_tab);
@@ -636,13 +633,6 @@ void RtpAnalysisDialog::on_actionSaveGraph_triggered()
}
}
-void RtpAnalysisDialog::on_buttonBox_clicked(QAbstractButton *button)
-{
- if (button == player_button_) {
- showPlayer();
- }
-}
-
void RtpAnalysisDialog::on_buttonBox_helpRequested()
{
wsApp->helpTopicAction(HELP_RTP_ANALYSIS_DIALOG);
@@ -959,45 +949,40 @@ void RtpAnalysisDialog::updateGraph()
ui->streamGraph->replot();
}
-void RtpAnalysisDialog::showPlayer()
+QVector<rtpstream_info_t *>RtpAnalysisDialog::getSelectedRtpStreams()
{
-#ifdef QT_MULTIMEDIA_LIB
- if (num_streams_ < 1) return;
+ QVector<rtpstream_info_t *> stream_infos;
+
+ if (num_streams_ > 0) {
+ stream_infos << &fwd_statinfo_;
- RtpPlayerDialog *rtp_player_dialog = new RtpPlayerDialog(*this, cap_file_);
- rtpstream_info_t stream_info;
-
- // XXX We might want to create an "rtp_stream_id_t" struct with only
- // addresses, ports & SSRC.
- rtpstream_info_init(&stream_info);
- rtpstream_id_copy(&fwd_statinfo_.id, &stream_info.id);
- stream_info.packet_count = fwd_statinfo_.packet_count;
- stream_info.setup_frame_number = fwd_statinfo_.setup_frame_number;
- stream_info.rtp_stats = fwd_statinfo_.rtp_stats;
- nstime_copy(&stream_info.start_rel_time, &fwd_statinfo_.start_rel_time);
- nstime_copy(&stream_info.stop_rel_time, &fwd_statinfo_.stop_rel_time);
- nstime_copy(&stream_info.start_abs_time, &fwd_statinfo_.start_abs_time);
- rtp_player_dialog->addRtpStream(&stream_info);
-
- if (num_streams_ > 1) {
- rtpstream_info_init(&stream_info);
- rtpstream_id_copy(&rev_statinfo_.id, &stream_info.id);
- stream_info.packet_count = rev_statinfo_.packet_count;
- stream_info.setup_frame_number = rev_statinfo_.setup_frame_number;
- stream_info.rtp_stats = rev_statinfo_.rtp_stats;
- nstime_copy(&stream_info.start_rel_time, &rev_statinfo_.start_rel_time);
- nstime_copy(&stream_info.stop_rel_time, &rev_statinfo_.stop_rel_time);
- nstime_copy(&stream_info.start_abs_time, &rev_statinfo_.start_abs_time);
- rtp_player_dialog->addRtpStream(&stream_info);
+ if (num_streams_ > 1) {
+ stream_infos << &rev_statinfo_;
+ }
}
- connect(rtp_player_dialog, SIGNAL(goToPacket(int)), this, SIGNAL(goToPacket(int)));
+ return stream_infos;
+}
+
+void RtpAnalysisDialog::rtpPlayerReplace()
+{
+ if (num_streams_ < 1) return;
+
+ emit rtpPlayerDialogReplaceRtpStreams(getSelectedRtpStreams());
+}
+
+void RtpAnalysisDialog::rtpPlayerAdd()
+{
+ if (num_streams_ < 1) return;
+
+ emit rtpPlayerDialogAddRtpStreams(getSelectedRtpStreams());
+}
+
+void RtpAnalysisDialog::rtpPlayerRemove()
+{
+ if (num_streams_ < 1) return;
- rtp_player_dialog->setWindowModality(Qt::ApplicationModal);
- rtp_player_dialog->setAttribute(Qt::WA_DeleteOnClose);
- rtp_player_dialog->setMarkers();
- rtp_player_dialog->show();
-#endif // QT_MULTIMEDIA_LIB
+ emit rtpPlayerDialogRemoveRtpStreams(getSelectedRtpStreams());
}
/* Convert one packet payload to samples in row */
diff --git a/ui/qt/rtp_analysis_dialog.h b/ui/qt/rtp_analysis_dialog.h
index ef9f4c05f2..8c0df74bdf 100644
--- a/ui/qt/rtp_analysis_dialog.h
+++ b/ui/qt/rtp_analysis_dialog.h
@@ -43,6 +43,14 @@ public:
signals:
void goToPacket(int packet_num);
+ void rtpPlayerDialogReplaceRtpStreams(QVector<rtpstream_info_t *> stream_infos);
+ void rtpPlayerDialogAddRtpStreams(QVector<rtpstream_info_t *> stream_infos);
+ void rtpPlayerDialogRemoveRtpStreams(QVector<rtpstream_info_t *> stream_infos);
+
+public slots:
+ void rtpPlayerReplace();
+ void rtpPlayerAdd();
+ void rtpPlayerRemove();
protected slots:
virtual void updateWidgets();
@@ -69,7 +77,6 @@ private slots:
void on_actionSaveForwardCsv_triggered();
void on_actionSaveReverseCsv_triggered();
void on_actionSaveGraph_triggered();
- void on_buttonBox_clicked(QAbstractButton *button);
void on_buttonBox_helpRequested();
void showStreamMenu(QPoint pos);
void graphClicked(QMouseEvent *event);
@@ -146,6 +153,7 @@ private:
void clearSAEErrors();
bool isSAEOK();
+ QVector<rtpstream_info_t *>getSelectedRtpStreams();
};
#endif // RTP_ANALYSIS_DIALOG_H
diff --git a/ui/qt/rtp_audio_stream.cpp b/ui/qt/rtp_audio_stream.cpp
index 0ffd759a95..bccaaf500f 100644
--- a/ui/qt/rtp_audio_stream.cpp
+++ b/ui/qt/rtp_audio_stream.cpp
@@ -131,6 +131,17 @@ void RtpAudioStream::addRtpPacket(const struct _packet_info *pinfo, const struct
rtp_packets_ << rtp_packet;
}
+void RtpAudioStream::clearPackets()
+{
+ for (int i = 0; i < rtp_packets_.size(); i++) {
+ rtp_packet_t *rtp_packet = rtp_packets_[i];
+ g_free(rtp_packet->info);
+ g_free(rtp_packet->payload_data);
+ g_free(rtp_packet);
+ }
+ rtp_packets_.clear();
+}
+
void RtpAudioStream::reset(double global_start_time)
{
global_start_rel_time_ = global_start_time;
diff --git a/ui/qt/rtp_audio_stream.h b/ui/qt/rtp_audio_stream.h
index e0c2a54dff..c5f57813d9 100644
--- a/ui/qt/rtp_audio_stream.h
+++ b/ui/qt/rtp_audio_stream.h
@@ -54,6 +54,7 @@ public:
bool isMatch(const rtpstream_info_t *rtpstream) const;
bool isMatch(const struct _packet_info *pinfo, const struct _rtp_info *rtp_info) const;
void addRtpPacket(const struct _packet_info *pinfo, const struct _rtp_info *rtp_info);
+ void clearPackets();
void reset(double global_start_time);
AudioRouting getAudioRouting();
void setAudioRouting(AudioRouting audio_routing);
diff --git a/ui/qt/rtp_player_dialog.cpp b/ui/qt/rtp_player_dialog.cpp
index 02424ab0db..f4691ddf0f 100644
--- a/ui/qt/rtp_player_dialog.cpp
+++ b/ui/qt/rtp_player_dialog.cpp
@@ -143,7 +143,7 @@ RtpPlayerDialog::RtpPlayerDialog(QWidget &parent, CaptureFile &cf) :
, stereo_available_(false)
, marker_stream_(0)
, last_ti_(0)
- , listener_removed_(false)
+ , listener_removed_(true)
{
ui->setupUi(this);
loadGeometry(parent.width(), parent.height());
@@ -279,11 +279,11 @@ RtpPlayerDialog::RtpPlayerDialog(QWidget &parent, CaptureFile &cf) :
list_ctx_menu_->addAction(ui->actionGoToSetupPacketTree);
set_action_shortcuts_visible_in_context_menu(list_ctx_menu_->actions());
- QTimer::singleShot(0, this, SLOT(retapPackets()));
#endif // QT_MULTIMEDIA_LIB
}
-QPushButton *RtpPlayerDialog::addPlayerButton(QDialogButtonBox *button_box)
+// _U_ is used when no QT_MULTIMEDIA_LIB is available
+QPushButton *RtpPlayerDialog::addPlayerButton(QDialogButtonBox *button_box, QDialog *dialog _U_)
{
if (!button_box) return NULL;
@@ -291,6 +291,26 @@ QPushButton *RtpPlayerDialog::addPlayerButton(QDialogButtonBox *button_box)
player_button = button_box->addButton(tr("&Play Streams"), QDialogButtonBox::ActionRole);
player_button->setToolTip(tr("Open RTP player dialog"));
player_button->setIcon(StockIcon("media-playback-start"));
+
+#if defined(QT_MULTIMEDIA_LIB)
+ QMenu *button_menu = new QMenu(player_button);
+ button_menu->setToolTipsVisible(true);
+ QAction *ca;
+ ca = button_menu->addAction(tr("Re&place"));
+ ca->setToolTip(tr("Replace existing streams in RTP Player with new set"));
+ connect(ca, SIGNAL(triggered()), dialog, SLOT(rtpPlayerReplace()));
+ ca = button_menu->addAction(tr("&Add"));
+ ca->setToolTip(tr("Add new set to existing list of streams in RTP Player"));
+ connect(ca, SIGNAL(triggered()), dialog, SLOT(rtpPlayerAdd()));
+ ca = button_menu->addAction(tr("&Remove"));
+ ca->setToolTip(tr("Remove selected streams from list of streams in RTP Player"));
+ connect(ca, SIGNAL(triggered()), dialog, SLOT(rtpPlayerRemove()));
+ player_button->setMenu(button_menu);
+#else
+ player_button->setEnabled(false);
+ player_button->setText(tr("No Audio"));
+#endif
+
return player_button;
}
@@ -334,15 +354,28 @@ void RtpPlayerDialog::reject()
void RtpPlayerDialog::retapPackets()
{
+ if (!listener_removed_) {
+ // Retap is running, nothing better we can do
+ return;
+ }
ui->hintLabel->setText("<i><small>" + tr("Decoding streams...") + "</i></small>");
wsApp->processEvents();
+ // Clear packets from existing streams before retap
+ for (int row = 0; row < ui->streamTreeWidget->topLevelItemCount(); row++) {
+ QTreeWidgetItem *ti = ui->streamTreeWidget->topLevelItem(row);
+ RtpAudioStream *row_stream = ti->data(stream_data_col_, Qt::UserRole).value<RtpAudioStream*>();
+
+ row_stream->clearPackets();
+ }
+
// destroyCheck is protection againts destroying dialog during recap.
// It stores dialog pointer in data() and if dialog destroyed, it
// returns null
QPointer<RtpPlayerDialog> destroyCheck=this;
GString *error_string;
+ listener_removed_ = false;
error_string = register_tap_listener("rtp", this, NULL, 0, NULL, tapPacket, NULL, NULL);
if (error_string) {
report_failure("RTP Player - tap registration failed: %s", error_string->str);
@@ -546,7 +579,7 @@ void RtpPlayerDialog::createPlot(bool rescale_axes)
if (rescale_axes) resetXAxis();
}
-void RtpPlayerDialog::addRtpStream(rtpstream_info_t *rtpstream)
+void RtpPlayerDialog::addSingleRtpStream(rtpstream_info_t *rtpstream)
{
AudioRouting audio_routing = AudioRouting(AUDIO_UNMUTED, channel_mono);
@@ -625,6 +658,63 @@ void RtpPlayerDialog::addRtpStream(rtpstream_info_t *rtpstream)
ui->streamTreeWidget->topLevelItemCount(),
rtpstream->packet_count,
rtpstream->start_fd ? rtpstream->start_fd->num : 0);
+
+}
+
+void RtpPlayerDialog::replaceRtpStreams(QVector<rtpstream_info_t *> stream_infos)
+{
+ // Delete all existing rows
+ on_actionSelectAll_triggered();
+ on_actionRemoveStream_triggered();
+
+ // Add all new streams
+ for (int i=0; i < stream_infos.size(); i++) {
+ addSingleRtpStream(stream_infos[i]);
+ }
+ setMarkers();
+
+ QTimer::singleShot(0, this, SLOT(retapPackets()));
+}
+
+void RtpPlayerDialog::addRtpStreams(QVector<rtpstream_info_t *> stream_infos)
+{
+ int tli_count = ui->streamTreeWidget->topLevelItemCount();
+
+ // Add new streams
+ for (int i=0; i < stream_infos.size(); i++) {
+ addSingleRtpStream(stream_infos[i]);
+ }
+
+ if (tli_count == 0) {
+ setMarkers();
+ }
+
+ QTimer::singleShot(0, this, SLOT(retapPackets()));
+}
+
+void RtpPlayerDialog::removeRtpStreams(QVector<rtpstream_info_t *> stream_infos)
+{
+ int tli_count = ui->streamTreeWidget->topLevelItemCount();
+
+ if (last_ti_) {
+ highlightItem(last_ti_, false);
+ last_ti_ = NULL;
+ }
+
+ for (int i=0; i < stream_infos.size(); i++) {
+ for (int row = 0; row < tli_count; row++) {
+ QTreeWidgetItem *ti = ui->streamTreeWidget->topLevelItem(row);
+ RtpAudioStream *row_stream = ti->data(stream_data_col_, Qt::UserRole).value<RtpAudioStream*>();
+ if (row_stream->isMatch(stream_infos[i])) {
+ removeRow(ti);
+ tli_count--;
+ break;
+ }
+ }
+ }
+ updateGraphs();
+
+ updateWidgets();
}
void RtpPlayerDialog::setMarkers()
@@ -1157,7 +1247,6 @@ void RtpPlayerDialog::outputNotify()
setPlayPosition(secs);
}
-
void RtpPlayerDialog::on_pauseButton_clicked()
{
for( int i = 0; i<playing_streams_.count(); ++i ) {
@@ -1274,56 +1363,58 @@ void RtpPlayerDialog::on_streamTreeWidget_itemDoubleClicked(QTreeWidgetItem *ite
}
}
-void RtpPlayerDialog::on_actionRemoveStream_triggered()
+void RtpPlayerDialog::removeRow(QTreeWidgetItem *ti)
{
- QList<QTreeWidgetItem *> items = ui->streamTreeWidget->selectedItems();
-
- if (last_ti_) {
- highlightItem(last_ti_, false);
- last_ti_ = NULL;
+ RtpAudioStream *audio_stream = ti->data(stream_data_col_, Qt::UserRole).value<RtpAudioStream*>();
+ if (audio_stream) {
+ ti->setData(stream_data_col_, Qt::UserRole, QVariant());
+ delete audio_stream;
}
- for(int i = 0; i<items.count(); i++ ) {
- QTreeWidgetItem *ti = items[i];
+ RtpAudioGraph *audio_graph = ti->data(graph_audio_data_col_, Qt::UserRole).value<RtpAudioGraph*>();
+ if (audio_graph) {
+ ti->setData(graph_audio_data_col_, Qt::UserRole, QVariant());
+ audio_graph->remove(ui->audioPlot);
+ }
- RtpAudioStream *audio_stream = ti->data(stream_data_col_, Qt::UserRole).value<RtpAudioStream*>();
- if (audio_stream) {
- ti->setData(stream_data_col_, Qt::UserRole, QVariant());
- delete audio_stream;
- }
+ QCPGraph *graph;
+ graph = ti->data(graph_sequence_data_col_, Qt::UserRole).value<QCPGraph*>();
+ if (graph) {
+ ti->setData(graph_sequence_data_col_, Qt::UserRole, QVariant());
+ ui->audioPlot->removeGraph(graph);
+ }
- RtpAudioGraph *audio_graph = ti->data(graph_audio_data_col_, Qt::UserRole).value<RtpAudioGraph*>();
- if (audio_graph) {
- ti->setData(graph_audio_data_col_, Qt::UserRole, QVariant());
- audio_graph->remove(ui->audioPlot);
- }
+ graph = ti->data(graph_jitter_data_col_, Qt::UserRole).value<QCPGraph*>();
+ if (graph) {
+ ti->setData(graph_jitter_data_col_, Qt::UserRole, QVariant());
+ ui->audioPlot->removeGraph(graph);
+ }
- QCPGraph *graph;
- graph = ti->data(graph_sequence_data_col_, Qt::UserRole).value<QCPGraph*>();
- if (graph) {
- ti->setData(graph_sequence_data_col_, Qt::UserRole, QVariant());
- ui->audioPlot->removeGraph(graph);
- }
+ graph = ti->data(graph_timestamp_data_col_, Qt::UserRole).value<QCPGraph*>();
+ if (graph) {
+ ti->setData(graph_timestamp_data_col_, Qt::UserRole, QVariant());
+ ui->audioPlot->removeGraph(graph);
+ }
- graph = ti->data(graph_jitter_data_col_, Qt::UserRole).value<QCPGraph*>();
- if (graph) {
- ti->setData(graph_jitter_data_col_, Qt::UserRole, QVariant());
- ui->audioPlot->removeGraph(graph);
- }
+ graph = ti->data(graph_silence_data_col_, Qt::UserRole).value<QCPGraph*>();
+ if (graph) {
+ ti->setData(graph_silence_data_col_, Qt::UserRole, QVariant());
+ ui->audioPlot->removeGraph(graph);
+ }
- graph = ti->data(graph_timestamp_data_col_, Qt::UserRole).value<QCPGraph*>();
- if (graph) {
- ti->setData(graph_timestamp_data_col_, Qt::UserRole, QVariant());
- ui->audioPlot->removeGraph(graph);
- }
+ delete ti;
+}
- graph = ti->data(graph_silence_data_col_, Qt::UserRole).value<QCPGraph*>();
- if (graph) {
- ti->setData(graph_silence_data_col_, Qt::UserRole, QVariant());
- ui->audioPlot->removeGraph(graph);
- }
+void RtpPlayerDialog::on_actionRemoveStream_triggered()
+{
+ QList<QTreeWidgetItem *> items = ui->streamTreeWidget->selectedItems();
- delete ti;
+ if (last_ti_) {
+ highlightItem(last_ti_, false);
+ last_ti_ = NULL;
+ }
+ for(int i = 0; i<items.count(); i++ ) {
+ removeRow(items[i]);
}
// TODO: Recalculate legend
// - Graphs used for legend could be removed above and we must add new
diff --git a/ui/qt/rtp_player_dialog.h b/ui/qt/rtp_player_dialog.h
index 8b0668102a..13a7c0bc70 100644
--- a/ui/qt/rtp_player_dialog.h
+++ b/ui/qt/rtp_player_dialog.h
@@ -52,7 +52,7 @@ public:
* @return The new "Play call" button.
*/
// XXX We might want to move this to qt_ui_utils.
- static QPushButton *addPlayerButton(QDialogButtonBox *button_box);
+ static QPushButton *addPlayerButton(QDialogButtonBox *button_box, QDialog *dialog);
#ifdef QT_MULTIMEDIA_LIB
~RtpPlayerDialog();
@@ -60,17 +60,19 @@ public:
void accept();
void reject();
- /** Add an RTP stream to play.
- * MUST be called before show().
- * Requires src_addr, src_port, dest_addr, dest_port, ssrc, packet_count,
- * setup_frame_number, and start_rel_time.
- *
- * @param rtpstream struct with rtpstream info
- */
- void addRtpStream(rtpstream_info_t *rtpstream);
void setMarkers();
public slots:
+ /** Replace/Add/Remove an RTP streams to play.
+ * Requires array of rtpstream_info_t.
+ * Each item must have filled items: src_addr, src_port, dest_addr,
+ * dest_port, ssrc, packet_count, setup_frame_number, and start_rel_time.
+ *
+ * @param rtpstream struct with rtpstream info
+ */
+ void replaceRtpStreams(QVector<rtpstream_info_t *> stream_infos);
+ void addRtpStreams(QVector<rtpstream_info_t *> stream_infos);
+ void removeRtpStreams(QVector<rtpstream_info_t *> stream_infos);
signals:
void goToPacket(int packet_num);
@@ -81,7 +83,7 @@ protected:
bool eventFilter(QObject *obj, QEvent *event);
private slots:
- /** Retap the capture file, adding RTP packets that match the
+ /** Retap the capture file, reading RTP packets that match the
* streams added using ::addRtpStream.
*/
void retapPackets();
@@ -190,6 +192,8 @@ private:
void highlightItem(QTreeWidgetItem *ti, bool highlight);
void invertSelection();
void handleGoToSetupPacket(QTreeWidgetItem *ti);
+ void addSingleRtpStream(rtpstream_info_t *rtpstream);
+ void removeRow(QTreeWidgetItem *ti);
#else // QT_MULTIMEDIA_LIB
private:
diff --git a/ui/qt/rtp_stream_dialog.cpp b/ui/qt/rtp_stream_dialog.cpp
index 82ecd907ff..9d025289ef 100644
--- a/ui/qt/rtp_stream_dialog.cpp
+++ b/ui/qt/rtp_stream_dialog.cpp
@@ -277,7 +277,7 @@ RtpStreamDialog::RtpStreamDialog(QWidget &parent, CaptureFile &cf) :
analyze_button_->setToolTip(ui->actionAnalyze->toolTip());
prepare_button_ = ui->buttonBox->addButton(ui->actionPrepareFilter->text(), QDialogButtonBox::ActionRole);
prepare_button_->setToolTip(ui->actionPrepareFilter->toolTip());
- player_button_ = RtpPlayerDialog::addPlayerButton(ui->buttonBox);
+ player_button_ = RtpPlayerDialog::addPlayerButton(ui->buttonBox, this);
copy_button_ = ui->buttonBox->addButton(ui->actionCopyButton->text(), QDialogButtonBox::ActionRole);
copy_button_->setToolTip(ui->actionCopyButton->toolTip());
export_button_ = ui->buttonBox->addButton(ui->actionExportAsRtpDump->text(), QDialogButtonBox::ActionRole);
@@ -545,9 +545,6 @@ void RtpStreamDialog::updateWidgets()
#if defined(QT_MULTIMEDIA_LIB)
player_button_->setEnabled(enable);
-#else
- player_button_->setEnabled(false);
- player_button_->setText(tr("No Audio"));
#endif
WiresharkDialog::updateWidgets();
@@ -812,8 +809,6 @@ void RtpStreamDialog::on_buttonBox_clicked(QAbstractButton *button)
on_actionExportAsRtpDump_triggered();
} else if (button == analyze_button_) {
on_actionAnalyze_triggered();
- } else if (button == player_button_) {
- showPlayer();
}
}
@@ -860,39 +855,40 @@ void RtpStreamDialog::on_actionSelectNone_triggered()
ui->streamTreeWidget->clearSelection();
}
-void RtpStreamDialog::showPlayer()
+QVector<rtpstream_info_t *>RtpStreamDialog::getSelectedRtpStreams()
{
- rtpstream_info_t stream_info;
- RtpPlayerDialog *rtp_player_dialog;
-
- if (ui->streamTreeWidget->selectedItems().count() < 1) return;
-#ifdef QT_MULTIMEDIA_LIB
- rtp_player_dialog = new RtpPlayerDialog(*this, cap_file_);
-
// Gather up our selected streams...
+ QVector<rtpstream_info_t *> stream_infos;
foreach(QTreeWidgetItem *ti, ui->streamTreeWidget->selectedItems()) {
RtpStreamTreeWidgetItem *rsti = static_cast<RtpStreamTreeWidgetItem*>(ti);
rtpstream_info_t *selected_stream = rsti->streamInfo();
if (selected_stream) {
- rtpstream_info_init(&stream_info);
- rtpstream_id_copy(&selected_stream->id, &stream_info.id);
- stream_info.packet_count = selected_stream->packet_count;
- stream_info.setup_frame_number = selected_stream->setup_frame_number;
- stream_info.rtp_stats = selected_stream->rtp_stats;
- nstime_copy(&stream_info.start_rel_time, &selected_stream->start_rel_time);
- nstime_copy(&stream_info.stop_rel_time, &selected_stream->stop_rel_time);
- nstime_copy(&stream_info.start_abs_time, &selected_stream->start_abs_time);
- rtp_player_dialog->addRtpStream(&stream_info);
+ stream_infos << selected_stream;
}
}
- connect(rtp_player_dialog, SIGNAL(goToPacket(int)), this, SIGNAL(goToPacket(int)));
+ return stream_infos;
+}
+
+void RtpStreamDialog::rtpPlayerReplace()
+{
+ if (ui->streamTreeWidget->selectedItems().count() < 1) return;
+
+ emit rtpPlayerDialogReplaceRtpStreams(getSelectedRtpStreams());
+}
+
+void RtpStreamDialog::rtpPlayerAdd()
+{
+ if (ui->streamTreeWidget->selectedItems().count() < 1) return;
+
+ emit rtpPlayerDialogAddRtpStreams(getSelectedRtpStreams());
+}
+
+void RtpStreamDialog::rtpPlayerRemove()
+{
+ if (ui->streamTreeWidget->selectedItems().count() < 1) return;
- rtp_player_dialog->setWindowModality(Qt::ApplicationModal);
- rtp_player_dialog->setAttribute(Qt::WA_DeleteOnClose);
- rtp_player_dialog->setMarkers();
- rtp_player_dialog->show();
-#endif // QT_MULTIMEDIA_LIB
+ emit rtpPlayerDialogRemoveRtpStreams(getSelectedRtpStreams());
}
void RtpStreamDialog::displayFilterSuccess(bool success)
diff --git a/ui/qt/rtp_stream_dialog.h b/ui/qt/rtp_stream_dialog.h
index cdf0395c23..7ac66bf15e 100644
--- a/ui/qt/rtp_stream_dialog.h
+++ b/ui/qt/rtp_stream_dialog.h
@@ -37,11 +37,17 @@ signals:
void packetsMarked();
void updateFilter(QString filter, bool force = false);
void goToPacket(int packet_num);
+ void rtpPlayerDialogReplaceRtpStreams(QVector<rtpstream_info_t *> stream_infos);
+ void rtpPlayerDialogAddRtpStreams(QVector<rtpstream_info_t *> stream_infos);
+ void rtpPlayerDialogRemoveRtpStreams(QVector<rtpstream_info_t *> stream_infos);
public slots:
void selectRtpStream(rtpstream_id_t *id);
void deselectRtpStream(rtpstream_id_t *id);
void displayFilterSuccess(bool success);
+ void rtpPlayerReplace();
+ void rtpPlayerAdd();
+ void rtpPlayerRemove();
protected:
bool eventFilter(QObject *obj, QEvent *event);
@@ -74,7 +80,7 @@ private:
QList<QVariant> streamRowData(int row) const;
void freeLastSelected();
void invertSelection();
-
+ QVector<rtpstream_info_t *>getSelectedRtpStreams();
private slots:
void showStreamMenu(QPoint pos);
diff --git a/ui/qt/sequence_dialog.cpp b/ui/qt/sequence_dialog.cpp
index 2e67ce6897..91f8ceaf36 100644
--- a/ui/qt/sequence_dialog.cpp
+++ b/ui/qt/sequence_dialog.cpp
@@ -72,7 +72,8 @@ SequenceDialog::SequenceDialog(QWidget &parent, CaptureFile &cf, SequenceInfo *i
info_(info),
num_items_(0),
packet_num_(0),
- sequence_w_(1)
+ sequence_w_(1),
+ voipFeaturesEnabled(false)
{
QAction *action;
@@ -152,9 +153,11 @@ SequenceDialog::SequenceDialog(QWidget &parent, CaptureFile &cf, SequenceInfo *i
ctx_menu_.addSeparator();
action = ui->actionSelectRtpStream;
ctx_menu_.addAction(action);
+ action->setVisible(false);
action->setEnabled(false);
action = ui->actionDeselectRtpStream;
ctx_menu_.addAction(action);
+ action->setVisible(false);
action->setEnabled(false);
set_action_shortcuts_visible_in_context_menu(ctx_menu_.actions());
@@ -176,6 +179,7 @@ SequenceDialog::SequenceDialog(QWidget &parent, CaptureFile &cf, SequenceInfo *i
reset_button_ = ui->buttonBox->addButton(ui->actionResetDiagram->text(), QDialogButtonBox::ActionRole);
reset_button_->setToolTip(ui->actionResetDiagram->toolTip());
+ player_button_ = RtpPlayerDialog::addPlayerButton(ui->buttonBox, this);
export_button_ = ui->buttonBox->addButton(ui->actionExportDiagram->text(), QDialogButtonBox::ActionRole);
export_button_->setToolTip(ui->actionExportDiagram->toolTip());
@@ -197,6 +201,10 @@ SequenceDialog::SequenceDialog(QWidget &parent, CaptureFile &cf, SequenceInfo *i
connect(sp, SIGNAL(mouseWheel(QWheelEvent*)), this, SLOT(mouseWheeled(QWheelEvent*)));
disconnect(ui->buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
+
+ // Button must be enabled by VoIP dialogs
+ player_button_->setVisible(false);
+ player_button_->setEnabled(false);
}
SequenceDialog::~SequenceDialog()
@@ -205,6 +213,14 @@ SequenceDialog::~SequenceDialog()
delete ui;
}
+void SequenceDialog::enableVoIPFeatures()
+{
+ voipFeaturesEnabled = true;
+ player_button_->setVisible(true);
+ ui->actionSelectRtpStream->setVisible(true);
+ ui->actionDeselectRtpStream->setVisible(true);
+}
+
void SequenceDialog::updateWidgets()
{
WiresharkDialog::updateWidgets();
@@ -279,10 +295,14 @@ void SequenceDialog::keyPressEvent(QKeyEvent *event)
on_actionGoToPreviousPacket_triggered();
break;
case Qt::Key_S:
- on_actionSelectRtpStream_triggered();
+ if (voipFeaturesEnabled) {
+ on_actionSelectRtpStream_triggered();
+ }
break;
case Qt::Key_D:
- on_actionDeselectRtpStream_triggered();
+ if (voipFeaturesEnabled) {
+ on_actionDeselectRtpStream_triggered();
+ }
break;
}
@@ -319,26 +339,29 @@ void SequenceDialog::yAxisChanged(QCPRange range)
void SequenceDialog::diagramClicked(QMouseEvent *event)
{
- switch (event->button()) {
- case Qt::LeftButton:
- on_actionGoToPacket_triggered();
- break;
- case Qt::RightButton:
- // XXX We should find some way to get sequenceDiagram to handle a
- // contextMenuEvent instead.
- current_rtp_sai_ = NULL;
- if (event) {
- seq_analysis_item_t *sai = seq_diagram_->itemForPosY(event->pos().y());
+ current_rtp_sai_ = NULL;
+ if (event) {
+ seq_analysis_item_t *sai = seq_diagram_->itemForPosY(event->pos().y());
+ if (voipFeaturesEnabled) {
ui->actionSelectRtpStream->setEnabled(false);
ui->actionDeselectRtpStream->setEnabled(false);
+ player_button_->setEnabled(false);
if (sai) {
if (GA_INFO_TYPE_RTP == sai->info_type) {
ui->actionSelectRtpStream->setEnabled(true && !file_closed_);
ui->actionDeselectRtpStream->setEnabled(true && !file_closed_);
+ player_button_->setEnabled(true && !file_closed_);
current_rtp_sai_ = sai;
}
}
}
+ }
+
+ switch (event->button()) {
+ case Qt::LeftButton:
+ on_actionGoToPacket_triggered();
+ break;
+ case Qt::RightButton:
ctx_menu_.exec(event->globalPos());
break;
default:
@@ -732,8 +755,7 @@ void SequenceDialog::on_actionZoomOut_triggered()
void SequenceDialog::on_actionSelectRtpStream_triggered()
{
if (current_rtp_sai_ && GA_INFO_TYPE_RTP == current_rtp_sai_->info_type) {
- emit openRtpStreamDialog();
- emit selectRtpStream((rtpstream_id_t *)current_rtp_sai_->info_ptr);
+ emit rtpStreamsDialogSelectRtpStream(&((rtpstream_info_t *)current_rtp_sai_->info_ptr)->id);
raise();
}
}
@@ -741,8 +763,7 @@ void SequenceDialog::on_actionSelectRtpStream_triggered()
void SequenceDialog::on_actionDeselectRtpStream_triggered()
{
if (current_rtp_sai_ && GA_INFO_TYPE_RTP == current_rtp_sai_->info_type) {
- emit openRtpStreamDialog();
- emit deselectRtpStream((rtpstream_id_t *)current_rtp_sai_->info_ptr);
+ emit rtpStreamsDialogDeselectRtpStream(&((rtpstream_info_t *)current_rtp_sai_->info_ptr)->id);
raise();
}
}
@@ -781,6 +802,32 @@ gboolean SequenceDialog::addFlowSequenceItem(const void* key, void *value, void
return FALSE;
}
+QVector<rtpstream_info_t *>SequenceDialog::getSelectedRtpStreams()
+{
+ QVector<rtpstream_info_t *> stream_infos;
+
+ if (current_rtp_sai_ && GA_INFO_TYPE_RTP == current_rtp_sai_->info_type) {
+ stream_infos << (rtpstream_info_t *)current_rtp_sai_->info_ptr;
+ }
+
+ return stream_infos;
+}
+
+void SequenceDialog::rtpPlayerReplace()
+{
+ emit rtpPlayerDialogReplaceRtpStreams(getSelectedRtpStreams());
+}
+
+void SequenceDialog::rtpPlayerAdd()
+{
+ emit rtpPlayerDialogAddRtpStreams(getSelectedRtpStreams());
+}
+
+void SequenceDialog::rtpPlayerRemove()
+{
+ emit rtpPlayerDialogRemoveRtpStreams(getSelectedRtpStreams());
+}
+
SequenceInfo::SequenceInfo(seq_analysis_info_t *sainfo) :
sainfo_(sainfo),
count_(1)
diff --git a/ui/qt/sequence_dialog.h b/ui/qt/sequence_dialog.h
index 655da6373b..c7e44c5163 100644
--- a/ui/qt/sequence_dialog.h
+++ b/ui/qt/sequence_dialog.h
@@ -51,6 +51,7 @@ class SequenceDialog : public WiresharkDialog
public:
explicit SequenceDialog(QWidget &parent, CaptureFile &cf, SequenceInfo *info = NULL);
~SequenceDialog();
+ void enableVoIPFeatures();
protected:
void showEvent(QShowEvent *event);
@@ -58,9 +59,11 @@ protected:
void keyPressEvent(QKeyEvent *event);
signals:
- void selectRtpStream(rtpstream_id_t *id);
- void deselectRtpStream(rtpstream_id_t *id);
- void openRtpStreamDialog();
+ void rtpStreamsDialogSelectRtpStream(rtpstream_id_t *id);
+ void rtpStreamsDialogDeselectRtpStream(rtpstream_id_t *id);
+ void rtpPlayerDialogReplaceRtpStreams(QVector<rtpstream_info_t *> stream_infos);
+ void rtpPlayerDialogAddRtpStreams(QVector<rtpstream_info_t *> stream_infos);
+ void rtpPlayerDialogRemoveRtpStreams(QVector<rtpstream_info_t *> stream_infos);
private slots:
void updateWidgets();
@@ -96,6 +99,10 @@ private slots:
void on_actionSelectRtpStream_triggered();
void on_actionDeselectRtpStream_triggered();
+ void rtpPlayerReplace();
+ void rtpPlayerAdd();
+ void rtpPlayerRemove();
+
private:
Ui::SequenceDialog *ui;
SequenceDiagram *seq_diagram_;
@@ -105,12 +112,14 @@ private:
double one_em_;
int sequence_w_;
QPushButton *reset_button_;
+ QPushButton *player_button_;
QPushButton *export_button_;
QMenu ctx_menu_;
QCPItemText *key_text_;
QCPItemText *comment_text_;
seq_analysis_item_t *current_rtp_sai_; // Used for passing current sai to rtp processing
QPointer<RtpStreamDialog> rtp_stream_dialog_; // Singleton pattern used
+ bool voipFeaturesEnabled;
void zoomXAxis(bool in);
void panAxes(int x_pixels, int y_pixels);
@@ -118,6 +127,8 @@ private:
void goToAdjacentPacket(bool next);
static gboolean addFlowSequenceItem(const void *key, void *value, void *userdata);
+
+ QVector<rtpstream_info_t *>getSelectedRtpStreams();
};
#endif // SEQUENCE_DIALOG_H
diff --git a/ui/qt/voip_calls_dialog.cpp b/ui/qt/voip_calls_dialog.cpp
index baee64095a..3ed76d9345 100644
--- a/ui/qt/voip_calls_dialog.cpp
+++ b/ui/qt/voip_calls_dialog.cpp
@@ -70,7 +70,7 @@ VoipCallsDialog::VoipCallsDialog(QWidget &parent, CaptureFile &cf, bool all_flow
sequence_button_->setToolTip(ui->actionFlowSequence->toolTip());
prepare_button_ = ui->buttonBox->addButton(ui->actionPrepareFilter->text(), QDialogButtonBox::ActionRole);
prepare_button_->setToolTip(ui->actionPrepareFilter->toolTip());
- player_button_ = RtpPlayerDialog::addPlayerButton(ui->buttonBox);
+ player_button_ = RtpPlayerDialog::addPlayerButton(ui->buttonBox, this);
connect (ui->todCheckBox, &QAbstractButton::toggled, this, &VoipCallsDialog::switchTimeOfDay);
@@ -377,9 +377,6 @@ void VoipCallsDialog::updateWidgets()
sequence_button_->setEnabled(enable);
#if defined(QT_MULTIMEDIA_LIB)
player_button_->setEnabled(enable);
-#else
- player_button_->setEnabled(false);
- player_button_->setText(tr("No Audio"));
#endif
WiresharkDialog::updateWidgets();
@@ -537,18 +534,20 @@ void VoipCallsDialog::showSequence()
}
SequenceDialog *sequence_dialog = new SequenceDialog(parent_, cap_file_, sequence_info_);
- connect(sequence_dialog, SIGNAL(selectRtpStream(rtpstream_id_t *)), this, SLOT(selectRtpStreamPassIn(rtpstream_id_t *)));
- connect(sequence_dialog, SIGNAL(deselectRtpStream(rtpstream_id_t *)), this, SLOT(deselectRtpStreamPassIn(rtpstream_id_t *)));
- connect(sequence_dialog, SIGNAL(openRtpStreamDialog()), this, SLOT(openRtpStreamDialogPassIn()));
+ // Bypass this dialog and forward signals to parent
+ connect(sequence_dialog, SIGNAL(rtpStreamsDialogSelectRtpStream(rtpstream_id_t *)), &parent_, SLOT(rtpStreamsDialogSelectRtpStream(rtpstream_id_t *)));
+ connect(sequence_dialog, SIGNAL(rtpStreamsDialogDeselectRtpStream(rtpstream_id_t *)), &parent_, SLOT(rtpStreamsDialogDeselectRtpStream(rtpstream_id_t *)));
+ connect(sequence_dialog, SIGNAL(rtpPlayerDialogReplaceRtpStreams(QVector<rtpstream_info_t *>)), &parent_, SLOT(rtpPlayerDialogReplaceRtpStreams(QVector<rtpstream_info_t *>)));
+ connect(sequence_dialog, SIGNAL(rtpPlayerDialogAddRtpStreams(QVector<rtpstream_info_t *>)), &parent_, SLOT(rtpPlayerDialogAddRtpStreams(QVector<rtpstream_info_t *>)));
+ connect(sequence_dialog, SIGNAL(rtpPlayerDialogRemoveRtpStreams(QVector<rtpstream_info_t *>)), &parent_, SLOT(rtpPlayerDialogRemoveRtpStreams(QVector<rtpstream_info_t *>)));
sequence_dialog->setAttribute(Qt::WA_DeleteOnClose);
+ sequence_dialog->enableVoIPFeatures();
sequence_dialog->show();
}
-void VoipCallsDialog::showPlayer()
+QVector<rtpstream_info_t *>VoipCallsDialog::getSelectedRtpStreams()
{
-#ifdef QT_MULTIMEDIA_LIB
- RtpPlayerDialog *rtp_player_dialog = new RtpPlayerDialog(*this, cap_file_);
-
+ QVector<rtpstream_info_t *> stream_infos;
foreach (QModelIndex index, ui->callTreeView->selectionModel()->selectedIndexes()) {
voip_calls_info_t *vci = VoipCallsInfoModel::indexToCallInfo(index);
if (!vci) continue;
@@ -562,18 +561,33 @@ void VoipCallsDialog::showPlayer()
// rsi->call_num, rsi->start_fd->num, rsi->setup_frame_number);
if (vci->call_num == static_cast<guint>(rsi->call_num)) {
//VOIP_CALLS_DEBUG("adding call number %u", vci->call_num);
- rtp_player_dialog->addRtpStream(rsi);
+ stream_infos << rsi;
}
}
}
- connect(rtp_player_dialog, SIGNAL(goToPacket(int)), this, SIGNAL(goToPacket(int)));
+ return stream_infos;
+}
+
+void VoipCallsDialog::rtpPlayerReplace()
+{
+ if (ui->callTreeView->selectionModel()->selectedIndexes().count() < 1) return;
+
+ emit rtpPlayerDialogReplaceRtpStreams(getSelectedRtpStreams());
+}
+
+void VoipCallsDialog::rtpPlayerAdd()
+{
+ if (ui->callTreeView->selectionModel()->selectedIndexes().count() < 1) return;
+
+ emit rtpPlayerDialogAddRtpStreams(getSelectedRtpStreams());
+}
+
+void VoipCallsDialog::rtpPlayerRemove()
+{
+ if (ui->callTreeView->selectionModel()->selectedIndexes().count() < 1) return;
- rtp_player_dialog->setWindowModality(Qt::ApplicationModal);
- rtp_player_dialog->setAttribute(Qt::WA_DeleteOnClose);
- rtp_player_dialog->setMarkers();
- rtp_player_dialog->show();
-#endif // QT_MULTIMEDIA_LIB
+ emit rtpPlayerDialogRemoveRtpStreams(getSelectedRtpStreams());
}
QList<QVariant> VoipCallsDialog::streamRowData(int row) const
@@ -649,8 +663,6 @@ void VoipCallsDialog::on_buttonBox_clicked(QAbstractButton *button)
prepareFilter();
} else if (button == sequence_button_) {
showSequence();
- } else if (button == player_button_) {
- showPlayer();
}
}
@@ -699,21 +711,6 @@ void VoipCallsDialog::switchTimeOfDay()
ui->callTreeView->resizeColumnToContents(VoipCallsInfoModel::StopTime);
}
-void VoipCallsDialog::selectRtpStreamPassIn(rtpstream_id_t *id)
-{
- emit selectRtpStreamPassOut(id);
-}
-
-void VoipCallsDialog::deselectRtpStreamPassIn(rtpstream_id_t *id)
-{
- emit deselectRtpStreamPassOut(id);
-}
-
-void VoipCallsDialog::openRtpStreamDialogPassIn()
-{
- emit openRtpStreamDialogPassOut();
-}
-
void VoipCallsDialog::displayFilterSuccess(bool success)
{
if (success && ui->displayFilterCheckBox->isChecked()) {
diff --git a/ui/qt/voip_calls_dialog.h b/ui/qt/voip_calls_dialog.h
index a5043c9b3b..2e7758be36 100644
--- a/ui/qt/voip_calls_dialog.h
+++ b/ui/qt/voip_calls_dialog.h
@@ -17,6 +17,8 @@
#include "cfile.h"
#include "ui/voip_calls.h"
+#include "ui/rtp_stream.h"
+#include "ui/rtp_stream_id.h"
#include <ui/qt/models/voip_calls_info_model.h>
#include <ui/qt/models/cache_proxy_model.h>
@@ -45,12 +47,15 @@ signals:
void updateFilter(QString filter, bool force = false);
void captureFileChanged(capture_file *cf);
void goToPacket(int packet_num);
- void selectRtpStreamPassOut(rtpstream_id_t *id);
- void deselectRtpStreamPassOut(rtpstream_id_t *id);
- void openRtpStreamDialogPassOut();
+ void rtpPlayerDialogReplaceRtpStreams(QVector<rtpstream_info_t *> stream_infos);
+ void rtpPlayerDialogAddRtpStreams(QVector<rtpstream_info_t *> stream_infos);
+ void rtpPlayerDialogRemoveRtpStreams(QVector<rtpstream_info_t *> stream_infos);
public slots:
void displayFilterSuccess(bool success);
+ void rtpPlayerReplace();
+ void rtpPlayerAdd();
+ void rtpPlayerRemove();
protected:
void contextMenuEvent(QContextMenuEvent *event);
@@ -92,6 +97,7 @@ private:
void invertSelection();
QList<QVariant> streamRowData(int row) const;
+ QVector<rtpstream_info_t *>getSelectedRtpStreams();
private slots:
void selectAll();
@@ -103,9 +109,6 @@ private slots:
void on_buttonBox_clicked(QAbstractButton *button);
void on_buttonBox_helpRequested();
void updateWidgets();
- void selectRtpStreamPassIn(rtpstream_id_t *id);
- void deselectRtpStreamPassIn(rtpstream_id_t *id);
- void openRtpStreamDialogPassIn();
void captureEvent(CaptureEvent e);
void on_displayFilterCheckBox_toggled(bool checked);
void on_actionSelectAll_triggered();
diff --git a/ui/voip_calls.c b/ui/voip_calls.c
index 7aada662aa..7893d59fce 100644
--- a/ui/voip_calls.c
+++ b/ui/voip_calls.c
@@ -768,8 +768,16 @@ rtp_draw(void *tap_offset_ptr)
(rtp_listinfo->is_srtp)?"SRTP":"RTP", rtp_listinfo->packet_count,
duration/1000, rtp_listinfo->id.ssrc);
new_gai->info_type=GA_INFO_TYPE_RTP;
- new_gai->info_ptr=g_new(rtpstream_id_t, 1);
- rtpstream_id_copy(&rtp_listinfo->id, (rtpstream_id_t *)new_gai->info_ptr);
+ rtpstream_info_t *new_info = g_new(rtpstream_info_t, 1);
+ new_gai->info_ptr = new_info;
+ rtpstream_info_init(new_info);
+ rtpstream_id_copy(&rtp_listinfo->id, &new_info->id);
+ new_info->packet_count = rtp_listinfo->packet_count;
+ new_info->setup_frame_number = rtp_listinfo->setup_frame_number;
+ new_info->rtp_stats = rtp_listinfo->rtp_stats;
+ nstime_copy(&new_info->start_rel_time, &rtp_listinfo->start_rel_time);
+ nstime_copy(&new_info->stop_rel_time, &rtp_listinfo->stop_rel_time);
+ nstime_copy(&new_info->start_abs_time, &rtp_listinfo->start_abs_time);
new_gai->conv_num = conv_num;
set_fd_time(tapinfo->session, rtp_listinfo->start_fd, time_str);
new_gai->time_str = g_strdup(time_str);