1 /* gsm_map_summary_dialog.cpp
3 * Wireshark - Network traffic analyzer
4 * By Gerald Combs <gerald@wireshark.org>
5 * Copyright 1998 Gerald Combs
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1998 Gerald Combs
11 * SPDX-License-Identifier: GPL-2.0-or-later
14 #include "gsm_map_summary_dialog.h"
15 #include <ui_gsm_map_summary_dialog.h>
19 #include "ui/summary.h"
21 #include <epan/packet.h>
23 #include <epan/asn1.h>
24 #include <epan/dissectors/packet-gsm_map.h>
26 #include "wsutil/utf8_entities.h"
28 #include "ui/capture_globals.h"
29 #include "ui/simple_dialog.h"
31 #include <ui/qt/utils/qt_ui_utils.h>
32 #include "main_application.h"
34 #include <QTextStream>
36 /** Gsm map statistic data */
37 typedef struct _gsm_map_stat_t
{
38 int opr_code
[GSM_MAP_MAX_NUM_OPR_CODES
];
39 int size
[GSM_MAP_MAX_NUM_OPR_CODES
];
40 int opr_code_rr
[GSM_MAP_MAX_NUM_OPR_CODES
];
41 int size_rr
[GSM_MAP_MAX_NUM_OPR_CODES
];
44 gsm_map_stat_t gsm_map_stat
;
46 GsmMapSummaryDialog::GsmMapSummaryDialog(QWidget
&parent
, CaptureFile
&capture_file
) :
47 WiresharkDialog(parent
, capture_file
),
48 ui(new Ui::GsmMapSummaryDialog
)
52 setWindowSubtitle(tr("GSM MAP Summary"));
56 GsmMapSummaryDialog::~GsmMapSummaryDialog()
61 // Copied from capture_file_properties_dialog.cpp
62 QString
GsmMapSummaryDialog::summaryToHtml()
64 summary_tally summary
;
65 memset(&summary
, 0, sizeof(summary_tally
));
68 QString table_begin
, table_end
;
69 QString table_row_begin
, table_ul_row_begin
, table_row_end
;
70 QString table_vheader_tmpl
;
71 QString table_data_tmpl
;
73 section_tmpl
= "<p><strong>%1</strong></p>\n";
74 table_begin
= "<p><table>\n";
75 table_end
= "</table></p>\n";
76 table_row_begin
= "<tr>\n";
77 table_ul_row_begin
= "<tr style=\"border-bottom: 1px solid gray;\">\n";
78 table_row_end
= "</tr>\n";
79 table_vheader_tmpl
= "<td width=\"50%\">%1:</td>"; // <th align="left"> looked odd
80 table_data_tmpl
= "<td>%1</td>";
82 if (cap_file_
.isValid()) {
83 /* initial computations */
84 summary_fill_in(cap_file_
.capFile(), &summary
);
86 summary_fill_in_capture(cap_file_
.capFile(), &global_capture_opts
, &summary
);
91 QTextStream
out(&summary_str
);
94 out
<< section_tmpl
.arg(tr("File"));
97 out
<< table_row_begin
98 << table_vheader_tmpl
.arg(tr("Name"))
99 << table_data_tmpl
.arg(summary
.filename
)
102 out
<< table_row_begin
103 << table_vheader_tmpl
.arg(tr("Length"))
104 << table_data_tmpl
.arg(file_size_to_qstring(summary
.file_length
))
107 QString format_str
= wtap_file_type_subtype_description(summary
.file_type
);
108 const char *compression_type_description
= wtap_compression_type_description(summary
.compression_type
);
109 if (compression_type_description
!= NULL
) {
110 format_str
+= QStringLiteral(" (%1)").arg(compression_type_description
);
112 out
<< table_row_begin
113 << table_vheader_tmpl
.arg(tr("Format"))
114 << table_data_tmpl
.arg(format_str
)
117 if (summary
.snap
!= 0) {
118 out
<< table_row_begin
119 << table_vheader_tmpl
.arg(tr("Snapshot length"))
120 << table_data_tmpl
.arg(summary
.snap
)
127 out
<< section_tmpl
.arg(tr("Data"));
130 if (summary
.packet_count_ts
== summary
.packet_count
&&
131 summary
.packet_count
>= 1)
134 out
<< table_row_begin
135 << table_vheader_tmpl
.arg(tr("First packet"))
136 << table_data_tmpl
.arg(time_t_to_qstring((time_t)summary
.start_time
))
140 out
<< table_row_begin
141 << table_vheader_tmpl
.arg(tr("Last packet"))
142 << table_data_tmpl
.arg(time_t_to_qstring((time_t)summary
.stop_time
))
145 // elapsed seconds (capture duration)
146 if (summary
.packet_count_ts
> 1)
148 /* elapsed seconds */
150 unsigned int elapsed_time
= (unsigned int)summary
.elapsed_time
;
151 if (elapsed_time
/86400)
153 elapsed_str
= QStringLiteral("%1 days ").arg(elapsed_time
/ 86400);
156 elapsed_str
+= QStringLiteral("%1:%2:%3")
157 .arg(elapsed_time
% 86400 / 3600, 2, 10, QChar('0'))
158 .arg(elapsed_time
% 3600 / 60, 2, 10, QChar('0'))
159 .arg(elapsed_time
% 60, 2, 10, QChar('0'));
160 out
<< table_row_begin
161 << table_vheader_tmpl
.arg(tr("Elapsed"))
162 << table_data_tmpl
.arg(elapsed_str
)
168 out
<< table_row_begin
169 << table_vheader_tmpl
.arg(tr("Packets"))
170 << table_data_tmpl
.arg(summary
.packet_count
)
175 QString n_a
= UTF8_EM_DASH
;
176 QString invoke_rate_str
, result_rate_str
, total_rate_str
;
177 QString invoke_avg_size_str
, result_avg_size_str
, total_avg_size_str
;
180 invoke_rate_str
= result_rate_str
= total_rate_str
= n_a
;
181 invoke_avg_size_str
= result_avg_size_str
= total_avg_size_str
= n_a
;
183 double seconds
= summary
.stop_time
- summary
.start_time
;
184 int invoke_count
= 0, invoke_bytes
= 0;
185 int result_count
= 0, result_bytes
= 0;
187 for (int i
= 0; i
< GSM_MAP_MAX_NUM_OPR_CODES
; i
++) {
188 invoke_count
+= gsm_map_stat
.opr_code
[i
];
189 invoke_bytes
+= gsm_map_stat
.size
[i
];
193 for (int i
= 0; i
< GSM_MAP_MAX_NUM_OPR_CODES
; i
++) {
194 result_count
+= gsm_map_stat
.opr_code_rr
[i
];
195 result_bytes
+= gsm_map_stat
.size_rr
[i
];
198 int total_count
= invoke_count
+ result_count
;
199 int total_bytes
= invoke_bytes
+ result_bytes
;
202 * We must have no un-time-stamped packets (i.e., the number of
203 * time-stamped packets must be the same as the number of packets),
204 * and at least two time-stamped packets, in order for the elapsed
207 if (summary
.packet_count_ts
> 1 && seconds
> 0.0) {
208 /* Total number of invokes per second */
209 invoke_rate_str
= QStringLiteral("%1").arg(invoke_count
/ seconds
, 1, 'f', 1);
210 result_rate_str
= QStringLiteral("%1").arg(result_count
/ seconds
, 1, 'f', 1);
211 total_rate_str
= QStringLiteral("%1").arg((total_count
) / seconds
, 1, 'f', 1);
214 /* Average message sizes */
215 if (invoke_count
> 0) {
216 invoke_avg_size_str
= QStringLiteral("%1").arg((double) invoke_bytes
/ invoke_count
, 1, 'f', 1);
218 if (result_count
> 0) {
219 result_avg_size_str
= QStringLiteral("%1").arg((double) result_bytes
/ result_count
, 1, 'f', 1);
221 if (total_count
> 0) {
222 total_avg_size_str
= QStringLiteral("%1").arg((double) total_bytes
/ total_count
, 1, 'f', 1);
226 out
<< section_tmpl
.arg(tr("Invokes"));
229 out
<< table_row_begin
230 << table_vheader_tmpl
.arg(tr("Total number of Invokes"))
231 << table_data_tmpl
.arg(invoke_count
)
234 out
<< table_row_begin
235 << table_vheader_tmpl
.arg(tr("Average number of Invokes per second"))
236 << table_data_tmpl
.arg(invoke_rate_str
)
239 out
<< table_row_begin
240 << table_vheader_tmpl
.arg(tr("Total number of bytes for Invokes"))
241 << table_data_tmpl
.arg(invoke_bytes
)
244 out
<< table_row_begin
245 << table_vheader_tmpl
.arg(tr("Average number of bytes per Invoke"))
246 << table_data_tmpl
.arg(invoke_avg_size_str
)
251 // Return Result Section
252 out
<< section_tmpl
.arg(tr("Return Results"));
255 out
<< table_row_begin
256 << table_vheader_tmpl
.arg(tr("Total number of Return Results"))
257 << table_data_tmpl
.arg(result_count
)
260 out
<< table_row_begin
261 << table_vheader_tmpl
.arg(tr("Average number of Return Results per second"))
262 << table_data_tmpl
.arg(result_rate_str
)
265 out
<< table_row_begin
266 << table_vheader_tmpl
.arg(tr("Total number of bytes for Return Results"))
267 << table_data_tmpl
.arg(result_bytes
)
270 out
<< table_row_begin
271 << table_vheader_tmpl
.arg(tr("Average number of bytes per Return Result"))
272 << table_data_tmpl
.arg(result_avg_size_str
)
278 out
<< section_tmpl
.arg(tr("Totals"));
281 out
<< table_row_begin
282 << table_vheader_tmpl
.arg(tr("Total number of GSM MAP messages"))
283 << table_data_tmpl
.arg(total_count
)
286 out
<< table_row_begin
287 << table_vheader_tmpl
.arg(tr("Average number of GSM MAP messages per second"))
288 << table_data_tmpl
.arg(total_rate_str
)
291 out
<< table_row_begin
292 << table_vheader_tmpl
.arg(tr("Total number of bytes for GSM MAP messages"))
293 << table_data_tmpl
.arg(total_bytes
)
296 out
<< table_row_begin
297 << table_vheader_tmpl
.arg(tr("Average number of bytes per GSM MAP message"))
298 << table_data_tmpl
.arg(total_avg_size_str
)
306 void GsmMapSummaryDialog::updateWidgets()
308 // QPushButton *refresh_bt = ui->buttonBox->button(QDialogButtonBox::Reset);
309 // QPushButton *save_bt = ui->buttonBox->button(QDialogButtonBox::Save);
311 // if (file_closed_) {
313 // refresh_bt->setEnabled(false);
315 // ui->commentsTextEdit->setReadOnly(true);
317 // save_bt->setEnabled(false);
322 ui
->summaryTextEdit
->setHtml(summaryToHtml());
324 WiresharkDialog::updateWidgets();
329 void register_tap_listener_qt_gsm_map_summary(void);
332 gsm_map_summary_reset(void *tapdata
)
334 gsm_map_stat_t
*gm_stat
= (gsm_map_stat_t
*)tapdata
;
336 memset(gm_stat
, 0, sizeof(gsm_map_stat_t
));
340 static tap_packet_status
341 gsm_map_summary_packet(void *tapdata
, packet_info
*, epan_dissect_t
*, const void *gmtr_ptr
, tap_flags_t flags _U_
)
343 gsm_map_stat_t
*gm_stat
= (gsm_map_stat_t
*)tapdata
;
344 const gsm_map_tap_rec_t
*gm_tap_rec
= (const gsm_map_tap_rec_t
*)gmtr_ptr
;
346 if (gm_tap_rec
->invoke
)
348 gm_stat
->opr_code
[gm_tap_rec
->opcode
]++;
349 gm_stat
->size
[gm_tap_rec
->opcode
] += gm_tap_rec
->size
;
353 gm_stat
->opr_code_rr
[gm_tap_rec
->opcode
]++;
354 gm_stat
->size_rr
[gm_tap_rec
->opcode
] += gm_tap_rec
->size
;
357 return(TAP_PACKET_DONT_REDRAW
); /* We have no draw callback */
361 register_tap_listener_qt_gsm_map_summary(void)
365 memset((void *) &gsm_map_stat
, 0, sizeof(gsm_map_stat_t
));
368 register_tap_listener("gsm_map", &gsm_map_stat
, NULL
, 0,
369 gsm_map_summary_reset
,
370 gsm_map_summary_packet
,
376 simple_dialog(ESD_TYPE_ERROR
, ESD_BTN_OK
, "%s", err_p
->str
);
377 g_string_free(err_p
, TRUE
);