1 /* rtp_analysis_dialog.h
2  *
3  * Wireshark - Network traffic analyzer
4  * By Gerald Combs <gerald@wireshark.org>
5  * Copyright 1998 Gerald Combs
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  */
9 
10 #ifndef RTP_ANALYSIS_DIALOG_H
11 #define RTP_ANALYSIS_DIALOG_H
12 
13 #include <config.h>
14 
15 #include <glib.h>
16 #include <mutex>
17 
18 #include "epan/address.h"
19 
20 #include "ui/rtp_stream.h"
21 #include "ui/tap-rtp-common.h"
22 #include "ui/tap-rtp-analysis.h"
23 
24 #include <QMenu>
25 #include <QTreeWidget>
26 #include <QLabel>
27 #include <QFile>
28 #include <QCheckBox>
29 #include <QHBoxLayout>
30 #include <QToolButton>
31 
32 #include "wireshark_dialog.h"
33 
34 namespace Ui {
35 class RtpAnalysisDialog;
36 }
37 
38 class QCPGraph;
39 class QTemporaryFile;
40 class QDialogButtonBox;
41 
42 typedef struct {
43     rtpstream_info_t stream;
44     QVector<double> *time_vals;
45     QVector<double> *jitter_vals;
46     QVector<double> *diff_vals;
47     QVector<double> *delta_vals;
48     QTreeWidget *tree_widget;
49     QLabel *statistics_label;
50     QString *tab_name;
51     QCPGraph *jitter_graph;
52     QCPGraph *diff_graph;
53     QCPGraph *delta_graph;
54     QHBoxLayout *graphHorizontalLayout;
55     QCheckBox *stream_checkbox;
56     QCheckBox *jitter_checkbox;
57     QCheckBox *diff_checkbox;
58     QCheckBox *delta_checkbox;
59 } tab_info_t;
60 
61 // Singleton by https://refactoring.guru/design-patterns/singleton/cpp/example#example-1
62 class RtpAnalysisDialog : public WiresharkDialog
63 {
64     Q_OBJECT
65 
66 public:
67     /**
68      * Returns singleton
69      */
70     static RtpAnalysisDialog *openRtpAnalysisDialog(QWidget &parent, CaptureFile &cf, QObject *packet_list);
71 
72     /**
73      * Should not be clonnable and assignable
74      */
75     RtpAnalysisDialog(RtpAnalysisDialog &other) = delete;
76     void operator=(const RtpAnalysisDialog &) = delete;
77 
78     /**
79      * @brief Common routine to add a "Analyze" button to a QDialogButtonBox.
80      * @param button_box Caller's QDialogButtonBox.
81      * @return The new "Analyze" button.
82      */
83     static QToolButton *addAnalyzeButton(QDialogButtonBox *button_box, QDialog *dialog);
84 
85     /** Replace/Add/Remove an RTP streams to analyse.
86      * Requires array of rtpstream_id_t.
87      *
88      * @param stream_ids structs with rtpstream_id
89      */
90     void replaceRtpStreams(QVector<rtpstream_id_t *> stream_ids);
91     void addRtpStreams(QVector<rtpstream_id_t *> stream_ids);
92     void removeRtpStreams(QVector<rtpstream_id_t *> stream_ids);
93 
94 signals:
95     void goToPacket(int packet_num);
96     void rtpPlayerDialogReplaceRtpStreams(QVector<rtpstream_id_t *> stream_ids);
97     void rtpPlayerDialogAddRtpStreams(QVector<rtpstream_id_t *> stream_ids);
98     void rtpPlayerDialogRemoveRtpStreams(QVector<rtpstream_id_t *> stream_ids);
99     void updateFilter(QString filter, bool force = false);
100 
101 public slots:
102     void rtpPlayerReplace();
103     void rtpPlayerAdd();
104     void rtpPlayerRemove();
105 
106 protected slots:
107     virtual void updateWidgets();
108 
109 protected:
110     explicit RtpAnalysisDialog(QWidget &parent, CaptureFile &cf);
111     ~RtpAnalysisDialog();
112 
113 private slots:
114     void on_actionGoToPacket_triggered();
115     void on_actionNextProblem_triggered();
116     void on_actionSaveOneCsv_triggered();
117     void on_actionSaveAllCsv_triggered();
118     void on_actionSaveGraph_triggered();
119     void on_buttonBox_helpRequested();
120     void showStreamMenu(QPoint pos);
121     void graphClicked(QMouseEvent *event);
122     void closeTab(int index);
123     void rowCheckboxChanged(int checked);
124     void singleCheckboxChanged(int checked);
125     void on_actionPrepareFilterOne_triggered();
126     void on_actionPrepareFilterAll_triggered();
127 
128 private:
129     static RtpAnalysisDialog *pinstance_;
130     static std::mutex mutex_;
131 
132     Ui::RtpAnalysisDialog *ui;
133     enum StreamDirection { dir_all_, dir_one_ };
134     int tab_seq;
135 
136     QVector<tab_info_t *> tabs_;
137     QMultiHash<guint, tab_info_t *> tab_hash_;
138 
139     QToolButton *player_button_;
140 
141     // Graph data for QCustomPlot
142     QList<QCPGraph *>graphs_;
143 
144     QString err_str_;
145 
146     QMenu stream_ctx_menu_;
147     QMenu graph_ctx_menu_;
148 
149     // Tap callbacks
150     static void tapReset(void *tapinfo_ptr);
151     static tap_packet_status tapPacket(void *tapinfo_ptr, packet_info *pinfo, epan_dissect_t *, const void *rtpinfo_ptr);
152     static void tapDraw(void *tapinfo_ptr);
153 
154     void resetStatistics();
155     void addPacket(tab_info_t *tab, packet_info *pinfo, const struct _rtp_info *rtpinfo);
156     void updateStatistics();
157     void updateGraph();
158 
159     void saveCsvHeader(QFile *save_file, QTreeWidget *tree);
160     void saveCsvData(QFile *save_file, QTreeWidget *tree);
161     void saveCsv(StreamDirection direction);
162 
163     bool eventFilter(QObject*, QEvent* event);
164 
165     QVector<rtpstream_id_t *>getSelectedRtpIds();
166     int addTabUI(tab_info_t *new_tab);
167     tab_info_t *getTabInfoForCurrentTab();
168     void deleteTabInfo(tab_info_t *tab_info);
169     void clearLayout(QLayout *layout);
170     void addRtpStreamsPrivate(QVector<rtpstream_id_t *> stream_ids);
171 };
172 
173 #endif // RTP_ANALYSIS_DIALOG_H
174