diff options
author | Jirka Novak <j.novak@netsystem.cz> | 2021-03-27 21:01:43 +0100 |
---|---|---|
committer | Wireshark GitLab Utility <gerald+gitlab-utility@wireshark.org> | 2021-03-30 07:57:22 +0000 |
commit | 47862d8fceffe75acb6db122dc355db084a315c6 (patch) | |
tree | 1584541fd8b5ada174055f07dfc311b56de55d3e /ui | |
parent | e43058ca592a4bff238126356d38546da2e677b5 (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
Diffstat (limited to 'ui')
-rw-r--r-- | ui/qt/main_window.h | 22 | ||||
-rw-r--r-- | ui/qt/main_window.ui | 8 | ||||
-rw-r--r-- | ui/qt/main_window_slots.cpp | 111 | ||||
-rw-r--r-- | ui/qt/rtp_analysis_dialog.cpp | 75 | ||||
-rw-r--r-- | ui/qt/rtp_analysis_dialog.h | 10 | ||||
-rw-r--r-- | ui/qt/rtp_audio_stream.cpp | 11 | ||||
-rw-r--r-- | ui/qt/rtp_audio_stream.h | 1 | ||||
-rw-r--r-- | ui/qt/rtp_player_dialog.cpp | 181 | ||||
-rw-r--r-- | ui/qt/rtp_player_dialog.h | 24 | ||||
-rw-r--r-- | ui/qt/rtp_stream_dialog.cpp | 54 | ||||
-rw-r--r-- | ui/qt/rtp_stream_dialog.h | 8 | ||||
-rw-r--r-- | ui/qt/sequence_dialog.cpp | 81 | ||||
-rw-r--r-- | ui/qt/sequence_dialog.h | 17 | ||||
-rw-r--r-- | ui/qt/voip_calls_dialog.cpp | 67 | ||||
-rw-r--r-- | ui/qt/voip_calls_dialog.h | 15 | ||||
-rw-r--r-- | ui/voip_calls.c | 12 |
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>&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); |