diff options
author | Jiri Novak <j.novak@netsystem.cz> | 2018-06-20 15:59:33 +0200 |
---|---|---|
committer | Anders Broman <a.broman58@gmail.com> | 2018-06-21 13:34:09 +0000 |
commit | d752f518cd810d58e886ded6edca89aa1b530451 (patch) | |
tree | 0b517a4f4abfba621ce736feb11af0449f0a3e24 /ui | |
parent | 5f45709d95321a4d469579fc59752e7b81ec63cf (diff) |
RTP: Stats calculation unification
Changes:
- rtpstream_info_calc_t created
- rtpstream_info_calculate and rtpstream_info_calc_free functions created
- RTP code updated to use such functions
Change-Id: I1053a46cbd0cdef9d70382135da46e732b5af8b8
Reviewed-on: https://code.wireshark.org/review/28361
Reviewed-by: Anders Broman <a.broman58@gmail.com>
Diffstat (limited to 'ui')
-rw-r--r-- | ui/cli/tap-rtp.c | 66 | ||||
-rw-r--r-- | ui/qt/rtp_stream_dialog.cpp | 52 | ||||
-rw-r--r-- | ui/tap-rtp-common.c | 83 | ||||
-rw-r--r-- | ui/tap-rtp-common.h | 37 |
4 files changed, 157 insertions, 81 deletions
diff --git a/ui/cli/tap-rtp.c b/ui/cli/tap-rtp.c index 65b1b62ba6..1d87dc58ef 100644 --- a/ui/cli/tap-rtp.c +++ b/ui/cli/tap-rtp.c @@ -45,16 +45,12 @@ static rtpstream_tapinfo_t the_tapinfo_struct = {NULL, NULL, NULL, NULL, 0, NULL, 0, TAP_ANALYSE, NULL, NULL, NULL, FALSE}; static void -rtp_streams_stat_draw(void *arg _U_) +rtp_streams_stat_draw_cb(void *arg _U_) { GList *list; rtpstream_info_t *strinfo; - gchar *payload_type; - guint32 expected; - gint32 lost; - double perc; + rtpstream_info_calc_t calc; char *savelocale; - char *src_addr, *dst_addr; printf("========================= RTP Streams ========================\n"); printf("%15s %5s %15s %5s %10s %16s %5s %12s %15s %15s %15s %s\n","Src IP addr", "Port", "Dest IP addr", "Port", "SSRC", "Payload", "Pkts", "Lost", "Max Delta(ms)", "Max Jitter(ms)", "Mean Jitter(ms)", "Problems?"); @@ -71,50 +67,26 @@ rtp_streams_stat_draw(void *arg _U_) while (list) { strinfo = (rtpstream_info_t*)(list->data); + rtpstream_info_calculate(strinfo, &calc); - /* payload type */ - if (strinfo->payload_type > 95) { - if (strinfo->payload_type_name != NULL) { - payload_type = wmem_strdup(NULL, strinfo->payload_type_name); - }else{ - payload_type = wmem_strdup_printf(NULL, "Unknown(%u)", strinfo->payload_type); - } - - }else{ - payload_type = val_to_str_ext_wmem(NULL, strinfo->payload_type, &rtp_payload_type_vals_ext, "Unknown (%u)"); - } - - /* packet count, lost packets */ - expected = (strinfo->rtp_stats.stop_seq_nr + strinfo->rtp_stats.cycles*65536) - - strinfo->rtp_stats.start_seq_nr + 1; - lost = expected - strinfo->rtp_stats.total_nr; - if (expected) { - perc = (double)(lost*100)/(double)expected; - } else { - perc = 0; - } - - src_addr = address_to_display(NULL, &(strinfo->id.src_addr)); - dst_addr = address_to_display(NULL, &(strinfo->id.dst_addr)); printf("%15s %5u %15s %5u 0x%08X %16s %5u %5d (%.1f%%) %15.2f %15.2f %15.2f %s\n", - src_addr, - strinfo->id.src_port, - dst_addr, - strinfo->id.dst_port, - strinfo->id.ssrc, - payload_type, - strinfo->packet_count, - lost, perc, - strinfo->rtp_stats.max_delta, - strinfo->rtp_stats.max_jitter, - strinfo->rtp_stats.mean_jitter, - (strinfo->problem)?"X":""); + calc.src_addr_str, + calc.src_port, + calc.dst_addr_str, + calc.dst_port, + calc.ssrc, + calc.payload_str, + calc.packet_count, + calc.lost_num, + calc.lost_perc, + calc.max_delta, + calc.max_jitter, + calc.mean_jitter, + (calc.problem)?"X":""); + + rtpstream_info_calc_free(&calc); list = g_list_next(list); - - wmem_free(NULL, src_addr); - wmem_free(NULL, dst_addr); - wmem_free(NULL, payload_type); } printf("==============================================================\n"); @@ -133,7 +105,7 @@ rtp_streams_stat_init(const char *opt_arg _U_, void *userdata _U_) register_tap_listener("rtp", &the_tapinfo_struct, NULL, 0, rtpstream_reset_cb, rtpstream_packet_cb, - rtp_streams_stat_draw); + rtp_streams_stat_draw_cb); if (err_p != NULL) { diff --git a/ui/qt/rtp_stream_dialog.cpp b/ui/qt/rtp_stream_dialog.cpp index 3951e2c4e0..1fa3034ccb 100644 --- a/ui/qt/rtp_stream_dialog.cpp +++ b/ui/qt/rtp_stream_dialog.cpp @@ -83,42 +83,26 @@ public: rtpstream_info_t *streamInfo() const { return stream_info_; } void drawData() { + rtpstream_info_calc_t calc; + if (!stream_info_) { return; } - setText(src_addr_col_, address_to_display_qstring(&stream_info_->id.src_addr)); - setText(src_port_col_, QString::number(stream_info_->id.src_port)); - setText(dst_addr_col_, address_to_display_qstring(&stream_info_->id.dst_addr)); - setText(dst_port_col_, QString::number(stream_info_->id.dst_port)); - setText(ssrc_col_, QString("0x%1").arg(stream_info_->id.ssrc, 0, 16)); - - if (stream_info_->payload_type_name != NULL) { - setText(payload_col_, stream_info_->payload_type_name); - } else { - setText(payload_col_, val_ext_to_qstring(stream_info_->payload_type, - &rtp_payload_type_short_vals_ext, - "Unknown (%u)")); - } - - setText(packets_col_, QString::number(stream_info_->packet_count)); - - guint32 expected; - double pct_loss; - expected = (stream_info_->rtp_stats.stop_seq_nr + stream_info_->rtp_stats.cycles*65536) - - stream_info_->rtp_stats.start_seq_nr + 1; - lost_ = expected - stream_info_->rtp_stats.total_nr; - if (expected) { - pct_loss = (double)(lost_*100.0)/(double)expected; - } else { - pct_loss = 0; - } - - setText(lost_col_, QObject::tr("%1 (%L2%)").arg(lost_).arg(QString::number(pct_loss, 'f', 1))); - setText(max_delta_col_, QString::number(stream_info_->rtp_stats.max_delta, 'f', 3)); // This is RTP. Do we need nanoseconds? - setText(max_jitter_col_, QString::number(stream_info_->rtp_stats.max_jitter, 'f', 3)); - setText(mean_jitter_col_, QString::number(stream_info_->rtp_stats.mean_jitter, 'f', 3)); - - if (stream_info_->problem) { + rtpstream_info_calculate(stream_info_, &calc); + + setText(src_addr_col_, calc.src_addr_str); + setText(src_port_col_, QString::number(calc.src_port)); + setText(dst_addr_col_, calc.dst_addr_str); + setText(dst_port_col_, QString::number(calc.dst_port)); + setText(ssrc_col_, QString("0x%1").arg(calc.ssrc, 0, 16)); + setText(payload_col_, calc.payload_str); + setText(packets_col_, QString::number(calc.packet_count)); + setText(lost_col_, QObject::tr("%1 (%L2%)").arg(calc.lost_num).arg(QString::number(calc.lost_perc, 'f', 1))); + setText(max_delta_col_, QString::number(calc.max_delta, 'f', 3)); // This is RTP. Do we need nanoseconds? + setText(max_jitter_col_, QString::number(calc.max_jitter, 'f', 3)); + setText(mean_jitter_col_, QString::number(calc.mean_jitter, 'f', 3)); + + if (calc.problem) { setText(status_col_, UTF8_BULLET); setTextAlignment(status_col_, Qt::AlignCenter); for (int i = 0; i < columnCount(); i++) { @@ -126,6 +110,8 @@ public: setTextColor(i, ws_css_warn_text); } } + + rtpstream_info_calc_free(&calc); } // Return a QString, int, double, or invalid QVariant representing the raw column data. QVariant colData(int col) const { diff --git a/ui/tap-rtp-common.c b/ui/tap-rtp-common.c index d2439c3449..4078b0b5c4 100644 --- a/ui/tap-rtp-common.c +++ b/ui/tap-rtp-common.c @@ -88,7 +88,7 @@ void rtpstream_reset(rtpstream_tapinfo_t *tapinfo) while (list) { g_free(list->data); - /* TODO free src_addr, dest_addr and payload_type_name? */ + /* TODO free src_addr, dst_addr and payload_type_name? */ list = g_list_next(list); } g_list_free(tapinfo->strinfo_list); @@ -290,6 +290,87 @@ int rtpstream_packet_cb(void *arg, packet_info *pinfo, epan_dissect_t *edt _U_, return 0; } +/****************************************************************************/ +/* evaluate rtp_stream_info_t calculations */ +/* - code is gathered from existing GTK/Qt/tui sources related to RTP statistics calculation + * - one place for calculations ensures that all wireshark tools shows same output for same input and avoids code duplication + */ +void rtpstream_info_calculate(const rtpstream_info_t *strinfo, rtpstream_info_calc_t *calc) +{ + double sumt; + double sumTS; + double sumt2; + double sumtTS; + double clock_drift_x; + guint32 clock_rate_x; + double duration_x; + + calc->src_addr_str = address_to_display(NULL, &(strinfo->id.src_addr)); + calc->src_port = strinfo->id.src_port; + calc->dst_addr_str = address_to_display(NULL, &(strinfo->id.dst_addr)); + calc->dst_port = strinfo->id.dst_port; + calc->ssrc = strinfo->id.ssrc; + + if (strinfo->payload_type > 95) { + if (strinfo->payload_type_name != NULL) { + calc->payload_str = wmem_strdup(NULL, strinfo->payload_type_name); + } else { + calc->payload_str = wmem_strdup_printf(NULL, "Unknown(%u)", strinfo->payload_type); + } + } else { + calc->payload_str = val_to_str_ext_wmem(NULL, strinfo->payload_type, &rtp_payload_type_vals_ext, "Unknown (%u)"); + } + + calc->packet_count = strinfo->packet_count; + /* packet count, lost packets */ + calc->packet_expected = (strinfo->rtp_stats.stop_seq_nr + strinfo->rtp_stats.cycles*65536) + - strinfo->rtp_stats.start_seq_nr + 1; + calc->total_nr = strinfo->rtp_stats.total_nr; + calc->lost_num = calc->packet_expected - strinfo->rtp_stats.total_nr; + if (calc->packet_expected) { + calc->lost_perc = (double)(calc->lost_num*100)/(double)calc->packet_expected; + } else { + calc->lost_perc = 0; + } + + calc->max_delta = strinfo->rtp_stats.max_delta; + calc->max_jitter = strinfo->rtp_stats.max_jitter; + calc->mean_jitter = strinfo->rtp_stats.mean_jitter; + calc->max_skew = strinfo->rtp_stats.max_skew; + calc->problem = strinfo->problem; + sumt = strinfo->rtp_stats.sumt; + sumTS = strinfo->rtp_stats.sumTS; + sumt2 = strinfo->rtp_stats.sumt2; + sumtTS = strinfo->rtp_stats.sumtTS; + duration_x = strinfo->rtp_stats.time - strinfo->rtp_stats.start_time; + + if ((calc->packet_count >0) && (sumt2 > 0)) { + clock_drift_x = (calc->packet_count * sumtTS - sumt * sumTS) / (calc->packet_count * sumt2 - sumt * sumt); + calc->clock_drift_ms = duration_x * (clock_drift_x - 1.0); + clock_rate_x = strinfo->rtp_stats.clock_rate * clock_drift_x; + calc->freq_drift_hz = clock_drift_x * clock_rate_x; + calc->freq_drift_perc = 100.0 * (clock_drift_x - 1.0); + } else { + calc->clock_drift_ms = 0.0; + calc->freq_drift_hz = 0.0; + calc->freq_drift_perc = 0.0; + } + calc->duration_ms = duration_x / 1000.0; + calc->sequence_err = strinfo->rtp_stats.sequence; + calc->start_time_ms = strinfo->rtp_stats.start_time / 1000.0; + calc->first_packet_num = strinfo->rtp_stats.first_packet_num; + calc->last_packet_num = strinfo->rtp_stats.max_nr; +} + +/****************************************************************************/ +/* free rtpstream_info_calc_t structure (internal items) */ +void rtpstream_info_calc_free(rtpstream_info_calc_t *calc) +{ + wmem_free(NULL, calc->src_addr_str); + wmem_free(NULL, calc->dst_addr_str); + wmem_free(NULL, calc->payload_str); +} + /* * Editor modelines - https://www.wireshark.org/tools/modelines.html * diff --git a/ui/tap-rtp-common.h b/ui/tap-rtp-common.h index 28db22476b..1ee3dbe38a 100644 --- a/ui/tap-rtp-common.h +++ b/ui/tap-rtp-common.h @@ -43,6 +43,33 @@ typedef struct _tap_rtp_save_info_t { gboolean saved; } tap_rtp_save_info_t; +typedef struct _rtp_stream_info_calc { + gchar *src_addr_str; + guint16 src_port; + gchar *dst_addr_str; + guint16 dst_port; + guint32 ssrc; + gchar *payload_str; /* Name of coded derived from fixed or dynamic codec names */ + guint32 packet_count; + guint32 total_nr; + guint32 packet_expected; /* Count of expected packets, derived from lenght of RTP stream */ + gint32 lost_num; + double lost_perc; + double max_delta; + double max_jitter; + double max_skew; + double mean_jitter; + gboolean problem; /* Indication that RTP stream contains something unusual -GUI should indicate it somehow */ + double clock_drift_ms; + double freq_drift_hz; + double freq_drift_perc; + double duration_ms; + guint32 sequence_err; + double start_time_ms; /**< Unit is ms */ + guint32 first_packet_num; + guint32 last_packet_num; +} rtpstream_info_calc_t; + /** * Compares two RTP stream infos (GCompareFunc style comparison function) * @@ -61,6 +88,16 @@ void rtpstream_reset_cb(void*); void rtp_write_header(rtpstream_info_t*, FILE*); int rtpstream_packet_cb(void*, packet_info*, epan_dissect_t *, const void *); +/** + * Evaluate rtp_stream_info_t calculations + */ +void rtpstream_info_calculate(const rtpstream_info_t *strinfo, rtpstream_info_calc_t *calc); + +/** + * Free rtpstream_info_calc_t structure (internal items) + */ +void rtpstream_info_calc_free(rtpstream_info_calc_t *calc); + #ifdef __cplusplus } #endif /* __cplusplus */ |