forked from osmocom/wireshark
RTP: Code clean up
Changes: - rtpstream_packet renamed to rtpstream_packet_cb to follow *_cb pattern - variables/types used in iax2_analysis_dialog were created as copy of *rtp* ones, but names were left as *rtp* -> *iax2* - struct _rtp_stream_info replaced with rtp_stream_info_t - there was tap-rtp-analysis.h, but no tap-rtp-analysis.c - related content was moved from tap-rtp-common.c - *rtp_stream* functions renamed to *rtpstream* - renamed rtp_stream_info_t to rtpstream_info_t to follow *rtpstream* pattern. - renamed ui/rtp_stream.c rtpstream_draw -> rtpstream_draw_cb Change-Id: Ib11ff5367cc464ea1b0c73432bc50b0eb9cd203e Reviewed-on: https://code.wireshark.org/review/28299 Reviewed-by: Anders Broman <a.broman58@gmail.com>
This commit is contained in:
parent
434fbe20dd
commit
27a1906c58
|
@ -50,6 +50,7 @@
|
|||
#include <ui/voip_calls.h>
|
||||
#include <ui/rtp_stream.h>
|
||||
#include <ui/tap-rtp-common.h>
|
||||
#include <ui/tap-rtp-analysis.h>
|
||||
#include <epan/to_str.h>
|
||||
|
||||
#include <epan/addr_resolv.h>
|
||||
|
@ -1335,7 +1336,7 @@ sharkd_session_packet_tap_rtp_analyse_cb(void *tapdata, packet_info *pinfo, epan
|
|||
tap_rtp_stat_t *statinfo = &(rtp_req->statinfo);
|
||||
struct sharkd_analyse_rtp_items *item;
|
||||
|
||||
rtp_packet_analyse(statinfo, pinfo, rtpinfo);
|
||||
rtppacket_analyse(statinfo, pinfo, rtpinfo);
|
||||
|
||||
item = (struct sharkd_analyse_rtp_items *) g_malloc(sizeof(struct sharkd_analyse_rtp_items));
|
||||
|
||||
|
@ -2095,7 +2096,7 @@ sharkd_session_process_tap_rtp_cb(void *arg)
|
|||
printf(",\"streams\":[");
|
||||
for (listx = g_list_first(rtp_tapinfo->strinfo_list); listx; listx = listx->next)
|
||||
{
|
||||
rtp_stream_info_t *streaminfo = (rtp_stream_info_t *) listx->data;
|
||||
rtpstream_info_t *streaminfo = (rtpstream_info_t *) listx->data;
|
||||
|
||||
char *src_addr, *dst_addr;
|
||||
char *payload;
|
||||
|
@ -2432,7 +2433,7 @@ sharkd_session_process_tap(char *buf, const jsmntok_t *tokens, int count)
|
|||
}
|
||||
else if (!strcmp(tok_tap, "rtp-streams"))
|
||||
{
|
||||
tap_error = register_tap_listener("rtp", &rtp_tapinfo, tap_filter, 0, rtpstream_reset_cb, rtpstream_packet, sharkd_session_process_tap_rtp_cb);
|
||||
tap_error = register_tap_listener("rtp", &rtp_tapinfo, tap_filter, 0, rtpstream_reset_cb, rtpstream_packet_cb, sharkd_session_process_tap_rtp_cb);
|
||||
|
||||
tap_data = &rtp_tapinfo;
|
||||
tap_free = rtpstream_reset_cb;
|
||||
|
|
|
@ -42,6 +42,7 @@ set(NONGENERATED_UI_SRC
|
|||
summary.c
|
||||
tap_export_pdu.c
|
||||
tap-iax2-analysis.c
|
||||
tap-rtp-analysis.c
|
||||
tap-rtp-common.c
|
||||
tap-sctp-analysis.c
|
||||
tap-rlc-graph.c
|
||||
|
|
|
@ -48,7 +48,7 @@ static void
|
|||
rtp_streams_stat_draw(void *arg _U_)
|
||||
{
|
||||
GList *list;
|
||||
rtp_stream_info_t *strinfo;
|
||||
rtpstream_info_t *strinfo;
|
||||
gchar *payload_type;
|
||||
guint32 expected;
|
||||
gint32 lost;
|
||||
|
@ -70,7 +70,7 @@ rtp_streams_stat_draw(void *arg _U_)
|
|||
list = g_list_first(list);
|
||||
while (list)
|
||||
{
|
||||
strinfo = (rtp_stream_info_t*)(list->data);
|
||||
strinfo = (rtpstream_info_t*)(list->data);
|
||||
|
||||
/* payload type */
|
||||
if (strinfo->payload_type > 95) {
|
||||
|
@ -132,7 +132,7 @@ rtp_streams_stat_init(const char *opt_arg _U_, void *userdata _U_)
|
|||
err_p =
|
||||
register_tap_listener("rtp", &the_tapinfo_struct, NULL, 0,
|
||||
rtpstream_reset_cb,
|
||||
rtpstream_packet,
|
||||
rtpstream_packet_cb,
|
||||
rtp_streams_stat_draw);
|
||||
|
||||
if (err_p != NULL)
|
||||
|
|
|
@ -358,7 +358,7 @@ Iax2AnalysisDialog::Iax2AnalysisDialog(QWidget &parent, CaptureFile &cf) :
|
|||
tapinfo.tap_data = this;
|
||||
tapinfo.mode = TAP_ANALYSE;
|
||||
|
||||
// register_tap_listener_rtp_stream(&tapinfo, NULL);
|
||||
// register_tap_listener_rtpstream(&tapinfo, NULL);
|
||||
/* Scan for RTP streams (redissect all packets) */
|
||||
rtpstream_scan(&tapinfo, cap_file_.capFile(), NULL);
|
||||
|
||||
|
@ -411,7 +411,7 @@ Iax2AnalysisDialog::Iax2AnalysisDialog(QWidget &parent, CaptureFile &cf) :
|
|||
Iax2AnalysisDialog::~Iax2AnalysisDialog()
|
||||
{
|
||||
delete ui;
|
||||
// remove_tap_listener_rtp_stream(&tapinfo);
|
||||
// remove_tap_listener_rtpstream(&tapinfo);
|
||||
delete fwd_tempfile_;
|
||||
delete rev_tempfile_;
|
||||
}
|
||||
|
|
|
@ -230,7 +230,7 @@ enum {
|
|||
num_graphs_
|
||||
};
|
||||
|
||||
RtpAnalysisDialog::RtpAnalysisDialog(QWidget &parent, CaptureFile &cf, struct _rtp_stream_info *stream_fwd, struct _rtp_stream_info *stream_rev) :
|
||||
RtpAnalysisDialog::RtpAnalysisDialog(QWidget &parent, CaptureFile &cf, rtpstream_info_t *stream_fwd, rtpstream_info_t *stream_rev) :
|
||||
WiresharkDialog(parent, cf),
|
||||
ui(new Ui::RtpAnalysisDialog),
|
||||
port_src_fwd_(0),
|
||||
|
@ -408,7 +408,7 @@ RtpAnalysisDialog::RtpAnalysisDialog(QWidget &parent, CaptureFile &cf, struct _r
|
|||
RtpAnalysisDialog::~RtpAnalysisDialog()
|
||||
{
|
||||
delete ui;
|
||||
// remove_tap_listener_rtp_stream(&tapinfo_);
|
||||
// remove_tap_listener_rtpstream(&tapinfo_);
|
||||
delete fwd_tempfile_;
|
||||
delete rev_tempfile_;
|
||||
}
|
||||
|
@ -760,7 +760,7 @@ void RtpAnalysisDialog::addPacket(bool forward, packet_info *pinfo, const _rtp_i
|
|||
// add_rtp_packet(rtpinfo, pinfo);
|
||||
|
||||
if (forward) {
|
||||
rtp_packet_analyse(&fwd_statinfo_, pinfo, rtpinfo);
|
||||
rtppacket_analyse(&fwd_statinfo_, pinfo, rtpinfo);
|
||||
new RtpAnalysisTreeWidgetItem(ui->forwardTreeWidget, &fwd_statinfo_, pinfo, rtpinfo);
|
||||
|
||||
fwd_time_vals_.append(fwd_statinfo_.time / 1000);
|
||||
|
@ -770,7 +770,7 @@ void RtpAnalysisDialog::addPacket(bool forward, packet_info *pinfo, const _rtp_i
|
|||
|
||||
savePayload(fwd_tempfile_, &fwd_statinfo_, pinfo, rtpinfo);
|
||||
} else {
|
||||
rtp_packet_analyse(&rev_statinfo_, pinfo, rtpinfo);
|
||||
rtppacket_analyse(&rev_statinfo_, pinfo, rtpinfo);
|
||||
new RtpAnalysisTreeWidgetItem(ui->reverseTreeWidget, &rev_statinfo_, pinfo, rtpinfo);
|
||||
|
||||
rev_time_vals_.append(rev_statinfo_.time / 1000);
|
||||
|
@ -854,7 +854,7 @@ void RtpAnalysisDialog::savePayload(QTemporaryFile *tmpfile, tap_rtp_stat_t *sta
|
|||
if (nchars != sizeof(save_data)) {
|
||||
/* Write error or short write */
|
||||
err_str_ = tr("Can't save in a file: File I/O problem.");
|
||||
save_payload_error_ = TAP_RTP_FILE_IO_ERROR;
|
||||
save_payload_error_ = TAP_RTP_FILE_WRITE_ERROR;
|
||||
tmpfile->close();
|
||||
return;
|
||||
}
|
||||
|
@ -863,7 +863,7 @@ void RtpAnalysisDialog::savePayload(QTemporaryFile *tmpfile, tap_rtp_stat_t *sta
|
|||
if (nchars != save_data.payload_len) {
|
||||
/* Write error or short write */
|
||||
err_str_ = tr("Can't save in a file: File I/O problem.");
|
||||
save_payload_error_ = TAP_RTP_FILE_IO_ERROR;
|
||||
save_payload_error_ = TAP_RTP_FILE_WRITE_ERROR;
|
||||
tmpfile->close();
|
||||
return;
|
||||
}
|
||||
|
@ -1037,7 +1037,7 @@ void RtpAnalysisDialog::showPlayer()
|
|||
if (num_streams_ < 1) return;
|
||||
|
||||
RtpPlayerDialog rtp_player_dialog(*this, cap_file_);
|
||||
rtp_stream_info_t stream_info;
|
||||
rtpstream_info_t stream_info;
|
||||
|
||||
// XXX We might want to create an "rtp_stream_id_t" struct with only
|
||||
// addresses, ports & SSRC.
|
||||
|
@ -1646,12 +1646,12 @@ void RtpAnalysisDialog::findStreams()
|
|||
tapinfo_.tap_data = this;
|
||||
tapinfo_.mode = TAP_ANALYSE;
|
||||
|
||||
// register_tap_listener_rtp_stream(&tapinfo_, NULL);
|
||||
// register_tap_listener_rtpstream(&tapinfo_, NULL);
|
||||
/* Scan for RTP streams (redissect all packets) */
|
||||
rtpstream_scan(&tapinfo_, cap_file_.capFile(), NULL);
|
||||
|
||||
for (GList *strinfo_list = g_list_first(tapinfo_.strinfo_list); strinfo_list; strinfo_list = g_list_next(strinfo_list)) {
|
||||
rtp_stream_info_t * strinfo = (rtp_stream_info_t*)(strinfo_list->data);
|
||||
rtpstream_info_t * strinfo = (rtpstream_info_t*)(strinfo_list->data);
|
||||
if (addresses_equal(&(strinfo->src_addr), &(src_fwd_))
|
||||
&& (strinfo->src_port == port_src_fwd_)
|
||||
&& (addresses_equal(&(strinfo->dest_addr), &(dst_fwd_)))
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "epan/address.h"
|
||||
|
||||
#include "ui/rtp_stream.h"
|
||||
#include "ui/tap-rtp-common.h"
|
||||
#include "ui/tap-rtp-analysis.h"
|
||||
|
||||
#include <QAbstractButton>
|
||||
|
@ -32,19 +33,12 @@ class RtpAnalysisDialog;
|
|||
class QCPGraph;
|
||||
class QTemporaryFile;
|
||||
|
||||
typedef enum {
|
||||
TAP_RTP_NO_ERROR,
|
||||
TAP_RTP_WRONG_LENGTH,
|
||||
TAP_RTP_PADDING_ERROR,
|
||||
TAP_RTP_FILE_IO_ERROR
|
||||
} rtp_error_type_t;
|
||||
|
||||
class RtpAnalysisDialog : public WiresharkDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit RtpAnalysisDialog(QWidget &parent, CaptureFile &cf, struct _rtp_stream_info *stream_fwd = 0, struct _rtp_stream_info *stream_rev = 0);
|
||||
explicit RtpAnalysisDialog(QWidget &parent, CaptureFile &cf, rtpstream_info_t *stream_fwd = 0, rtpstream_info_t *stream_rev = 0);
|
||||
~RtpAnalysisDialog();
|
||||
|
||||
signals:
|
||||
|
@ -132,7 +126,7 @@ private:
|
|||
|
||||
rtpstream_tapinfo_t tapinfo_;
|
||||
QString err_str_;
|
||||
rtp_error_type_t save_payload_error_;
|
||||
tap_rtp_error_type_t save_payload_error_;
|
||||
|
||||
QMenu stream_ctx_menu_;
|
||||
QMenu graph_ctx_menu_;
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
static spx_int16_t default_audio_sample_rate_ = 8000;
|
||||
static const spx_int16_t visual_sample_rate_ = 1000;
|
||||
|
||||
RtpAudioStream::RtpAudioStream(QObject *parent, _rtp_stream_info *rtp_stream) :
|
||||
RtpAudioStream::RtpAudioStream(QObject *parent, rtpstream_info_t *rtp_stream) :
|
||||
QObject(parent),
|
||||
decoders_hash_(rtp_decoder_hash_table_new()),
|
||||
global_start_rel_time_(0.0),
|
||||
|
@ -84,7 +84,7 @@ RtpAudioStream::~RtpAudioStream()
|
|||
speex_resampler_destroy (visual_resampler_);
|
||||
}
|
||||
|
||||
bool RtpAudioStream::isMatch(const _rtp_stream_info *rtp_stream) const
|
||||
bool RtpAudioStream::isMatch(const rtpstream_info_t *rtp_stream) const
|
||||
{
|
||||
if (rtp_stream
|
||||
&& addresses_equal(&rtp_stream->src_addr, &src_addr_)
|
||||
|
@ -111,7 +111,7 @@ bool RtpAudioStream::isMatch(const _packet_info *pinfo, const _rtp_info *rtp_inf
|
|||
// XXX We add multiple RTP streams here because that's what the GTK+ UI does.
|
||||
// Should we make these distinct, with their own waveforms? It seems like
|
||||
// that would simplify a lot of things.
|
||||
void RtpAudioStream::addRtpStream(const _rtp_stream_info *rtp_stream)
|
||||
void RtpAudioStream::addRtpStream(const rtpstream_info_t *rtp_stream)
|
||||
{
|
||||
if (!rtp_stream) return;
|
||||
|
||||
|
@ -296,7 +296,7 @@ void RtpAudioStream::decode()
|
|||
silence_timestamps_.append(stop_rel_time_);
|
||||
|
||||
decoded_bytes_prev = 0;
|
||||
/* defined start_timestmp to avoid overflow in timestamp. TODO: handle the timestamp correctly */
|
||||
/* defined start_timestamp to avoid overflow in timestamp. TODO: handle the timestamp correctly */
|
||||
/* XXX: if timestamps (RTP) are missing/ignored try use packet arrive time only (see also "rtp_time") */
|
||||
start_timestamp = rtp_packet->info->info_timestamp;
|
||||
start_rtp_time = 0;
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include <glib.h>
|
||||
|
||||
#include <epan/address.h>
|
||||
#include <ui/rtp_stream.h>
|
||||
|
||||
#include <QAudio>
|
||||
#include <QColor>
|
||||
|
@ -30,7 +31,6 @@ class QAudioOutput;
|
|||
class QTemporaryFile;
|
||||
|
||||
struct _rtp_info;
|
||||
struct _rtp_stream_info;
|
||||
struct _rtp_sample;
|
||||
|
||||
class RtpAudioStream : public QObject
|
||||
|
@ -39,11 +39,11 @@ class RtpAudioStream : public QObject
|
|||
public:
|
||||
enum TimingMode { JitterBuffer, RtpTimestamp, Uninterrupted };
|
||||
|
||||
explicit RtpAudioStream(QObject *parent, struct _rtp_stream_info *rtp_stream);
|
||||
explicit RtpAudioStream(QObject *parent, rtpstream_info_t *rtp_stream);
|
||||
~RtpAudioStream();
|
||||
bool isMatch(const struct _rtp_stream_info *rtp_stream) const;
|
||||
bool isMatch(const rtpstream_info_t *rtp_stream) const;
|
||||
bool isMatch(const struct _packet_info *pinfo, const struct _rtp_info *rtp_info) const;
|
||||
void addRtpStream(const struct _rtp_stream_info *rtp_stream);
|
||||
void addRtpStream(const rtpstream_info_t *rtp_stream);
|
||||
void addRtpPacket(const struct _packet_info *pinfo, const struct _rtp_info *rtp_info);
|
||||
void reset(double start_rel_time);
|
||||
void decode();
|
||||
|
@ -150,7 +150,7 @@ private:
|
|||
QVector<struct _rtp_packet *>rtp_packets_;
|
||||
QTemporaryFile *tempfile_;
|
||||
struct _GHashTable *decoders_hash_;
|
||||
QList<const struct _rtp_stream_info *>rtp_streams_;
|
||||
QList<const rtpstream_info_t *>rtp_streams_;
|
||||
double global_start_rel_time_;
|
||||
double start_abs_offset_;
|
||||
double start_rel_time_;
|
||||
|
|
|
@ -353,7 +353,7 @@ void RtpPlayerDialog::rescanPackets(bool rescale_axes)
|
|||
updateWidgets();
|
||||
}
|
||||
|
||||
void RtpPlayerDialog::addRtpStream(struct _rtp_stream_info *rtp_stream)
|
||||
void RtpPlayerDialog::addRtpStream(rtpstream_info_t *rtp_stream)
|
||||
{
|
||||
if (!rtp_stream) return;
|
||||
|
||||
|
@ -771,7 +771,7 @@ void RtpPlayerDialog::on_buttonBox_helpRequested()
|
|||
#if 0
|
||||
// This also serves as a title in RtpAudioFrame.
|
||||
static const QString stream_key_tmpl_ = "%1:%2 " UTF8_RIGHTWARDS_ARROW " %3:%4 0x%5";
|
||||
const QString RtpPlayerDialog::streamKey(const struct _rtp_stream_info *rtp_stream)
|
||||
const QString RtpPlayerDialog::streamKey(const rtpstream_info_t *rtp_stream)
|
||||
{
|
||||
const QString stream_key = QString(stream_key_tmpl_)
|
||||
.arg(address_to_display_qstring(&rtp_stream->src_addr))
|
||||
|
|
|
@ -24,8 +24,6 @@ namespace Ui {
|
|||
class RtpPlayerDialog;
|
||||
}
|
||||
|
||||
struct _rtp_stream_info;
|
||||
|
||||
class QCPItemStraightLine;
|
||||
class QDialogButtonBox;
|
||||
class QMenu;
|
||||
|
@ -62,7 +60,7 @@ public:
|
|||
*
|
||||
* @param rtp_stream struct with rtp_stream info
|
||||
*/
|
||||
void addRtpStream(struct _rtp_stream_info *rtp_stream);
|
||||
void addRtpStream(rtpstream_info_t *rtp_stream);
|
||||
|
||||
public slots:
|
||||
|
||||
|
@ -115,7 +113,7 @@ private:
|
|||
QCPItemStraightLine *cur_play_pos_;
|
||||
QString playback_error_;
|
||||
|
||||
// const QString streamKey(const struct _rtp_stream_info *rtp_stream);
|
||||
// const QString streamKey(const rtp_stream_info_t *rtp_stream);
|
||||
// const QString streamKey(const packet_info *pinfo, const struct _rtp_info *rtpinfo);
|
||||
|
||||
// Tap callbacks
|
||||
|
|
|
@ -73,14 +73,14 @@ enum { rtp_stream_type_ = 1000 };
|
|||
class RtpStreamTreeWidgetItem : public QTreeWidgetItem
|
||||
{
|
||||
public:
|
||||
RtpStreamTreeWidgetItem(QTreeWidget *tree, rtp_stream_info_t *stream_info) :
|
||||
RtpStreamTreeWidgetItem(QTreeWidget *tree, rtpstream_info_t *stream_info) :
|
||||
QTreeWidgetItem(tree, rtp_stream_type_),
|
||||
stream_info_(stream_info)
|
||||
{
|
||||
drawData();
|
||||
}
|
||||
|
||||
rtp_stream_info_t *streamInfo() const { return stream_info_; }
|
||||
rtpstream_info_t *streamInfo() const { return stream_info_; }
|
||||
|
||||
void drawData() {
|
||||
if (!stream_info_) {
|
||||
|
@ -199,7 +199,7 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
rtp_stream_info_t *stream_info_;
|
||||
rtpstream_info_t *stream_info_;
|
||||
guint32 lost_;
|
||||
};
|
||||
|
||||
|
@ -258,7 +258,7 @@ RtpStreamDialog::RtpStreamDialog(QWidget &parent, CaptureFile &cf) :
|
|||
tapinfo_.tap_data = this;
|
||||
tapinfo_.mode = TAP_ANALYSE;
|
||||
|
||||
register_tap_listener_rtp_stream(&tapinfo_, NULL);
|
||||
register_tap_listener_rtpstream(&tapinfo_, NULL);
|
||||
/* Scan for RTP streams (redissect all packets) */
|
||||
rtpstream_scan(&tapinfo_, cf.capFile(), NULL);
|
||||
|
||||
|
@ -268,7 +268,7 @@ RtpStreamDialog::RtpStreamDialog(QWidget &parent, CaptureFile &cf) :
|
|||
RtpStreamDialog::~RtpStreamDialog()
|
||||
{
|
||||
delete ui;
|
||||
remove_tap_listener_rtp_stream(&tapinfo_);
|
||||
remove_tap_listener_rtpstream(&tapinfo_);
|
||||
}
|
||||
|
||||
bool RtpStreamDialog::eventFilter(QObject *, QEvent *event)
|
||||
|
@ -336,7 +336,7 @@ void RtpStreamDialog::updateStreams()
|
|||
|
||||
// Add any missing items
|
||||
while (cur_stream && cur_stream->data) {
|
||||
rtp_stream_info_t *stream_info = (rtp_stream_info_t*) cur_stream->data;
|
||||
rtpstream_info_t *stream_info = (rtpstream_info_t*) cur_stream->data;
|
||||
new RtpStreamTreeWidgetItem(ui->streamTreeWidget, stream_info);
|
||||
cur_stream = g_list_next(cur_stream);
|
||||
}
|
||||
|
@ -432,7 +432,7 @@ QList<QVariant> RtpStreamDialog::streamRowData(int row) const
|
|||
|
||||
void RtpStreamDialog::captureFileClosing()
|
||||
{
|
||||
remove_tap_listener_rtp_stream(&tapinfo_);
|
||||
remove_tap_listener_rtpstream(&tapinfo_);
|
||||
WiresharkDialog::captureFileClosing();
|
||||
}
|
||||
|
||||
|
@ -443,7 +443,7 @@ void RtpStreamDialog::showStreamMenu(QPoint pos)
|
|||
|
||||
void RtpStreamDialog::on_actionAnalyze_triggered()
|
||||
{
|
||||
rtp_stream_info_t *stream_a, *stream_b = NULL;
|
||||
rtpstream_info_t *stream_a, *stream_b = NULL;
|
||||
|
||||
QTreeWidgetItem *ti = ui->streamTreeWidget->selectedItems()[0];
|
||||
RtpStreamTreeWidgetItem *rsti = static_cast<RtpStreamTreeWidgetItem*>(ti);
|
||||
|
@ -502,7 +502,7 @@ void RtpStreamDialog::on_actionExportAsRtpDump_triggered()
|
|||
// XXX If the user selected multiple frames is this the one we actually want?
|
||||
QTreeWidgetItem *ti = ui->streamTreeWidget->selectedItems()[0];
|
||||
RtpStreamTreeWidgetItem *rsti = static_cast<RtpStreamTreeWidgetItem*>(ti);
|
||||
rtp_stream_info_t *stream_info = rsti->streamInfo();
|
||||
rtpstream_info_t *stream_info = rsti->streamInfo();
|
||||
if (stream_info) {
|
||||
QString file_name;
|
||||
QDir path(wsApp->lastOpenDir());
|
||||
|
@ -530,10 +530,10 @@ void RtpStreamDialog::on_actionFindReverse_triggered()
|
|||
if (ui->streamTreeWidget->selectedItems().count() < 1) return;
|
||||
|
||||
// Gather up our selected streams...
|
||||
QList<rtp_stream_info_t *> selected_streams;
|
||||
QList<rtpstream_info_t *> selected_streams;
|
||||
foreach(QTreeWidgetItem *ti, ui->streamTreeWidget->selectedItems()) {
|
||||
RtpStreamTreeWidgetItem *rsti = static_cast<RtpStreamTreeWidgetItem*>(ti);
|
||||
rtp_stream_info_t *stream_info = rsti->streamInfo();
|
||||
rtpstream_info_t *stream_info = rsti->streamInfo();
|
||||
if (stream_info) {
|
||||
selected_streams << stream_info;
|
||||
}
|
||||
|
@ -543,10 +543,10 @@ void RtpStreamDialog::on_actionFindReverse_triggered()
|
|||
QTreeWidgetItemIterator iter(ui->streamTreeWidget, QTreeWidgetItemIterator::Unselected);
|
||||
while (*iter) {
|
||||
RtpStreamTreeWidgetItem *rsti = static_cast<RtpStreamTreeWidgetItem*>(*iter);
|
||||
rtp_stream_info_t *stream_info = rsti->streamInfo();
|
||||
rtpstream_info_t *stream_info = rsti->streamInfo();
|
||||
if (stream_info) {
|
||||
foreach (rtp_stream_info_t *fwd_stream, selected_streams) {
|
||||
if (rtp_stream_info_is_reverse(fwd_stream, stream_info)) {
|
||||
foreach (rtpstream_info_t *fwd_stream, selected_streams) {
|
||||
if (rtpstream_info_is_reverse(fwd_stream, stream_info)) {
|
||||
(*iter)->setSelected(true);
|
||||
}
|
||||
}
|
||||
|
@ -561,7 +561,7 @@ void RtpStreamDialog::on_actionGoToSetup_triggered()
|
|||
// XXX If the user selected multiple frames is this the one we actually want?
|
||||
QTreeWidgetItem *ti = ui->streamTreeWidget->selectedItems()[0];
|
||||
RtpStreamTreeWidgetItem *rsti = static_cast<RtpStreamTreeWidgetItem*>(ti);
|
||||
rtp_stream_info_t *stream_info = rsti->streamInfo();
|
||||
rtpstream_info_t *stream_info = rsti->streamInfo();
|
||||
if (stream_info) {
|
||||
emit goToPacket(stream_info->setup_frame_number);
|
||||
}
|
||||
|
@ -570,7 +570,7 @@ void RtpStreamDialog::on_actionGoToSetup_triggered()
|
|||
void RtpStreamDialog::on_actionMarkPackets_triggered()
|
||||
{
|
||||
if (ui->streamTreeWidget->selectedItems().count() < 1) return;
|
||||
rtp_stream_info_t *stream_a, *stream_b = NULL;
|
||||
rtpstream_info_t *stream_a, *stream_b = NULL;
|
||||
|
||||
QTreeWidgetItem *ti = ui->streamTreeWidget->selectedItems()[0];
|
||||
RtpStreamTreeWidgetItem *rsti = static_cast<RtpStreamTreeWidgetItem*>(ti);
|
||||
|
@ -597,7 +597,7 @@ void RtpStreamDialog::on_actionPrepareFilter_triggered()
|
|||
QStringList stream_filters;
|
||||
foreach(QTreeWidgetItem *ti, ui->streamTreeWidget->selectedItems()) {
|
||||
RtpStreamTreeWidgetItem *rsti = static_cast<RtpStreamTreeWidgetItem*>(ti);
|
||||
rtp_stream_info_t *stream_info = rsti->streamInfo();
|
||||
rtpstream_info_t *stream_info = rsti->streamInfo();
|
||||
if (stream_info) {
|
||||
QString ip_proto = stream_info->src_addr.type == AT_IPv6 ? "ipv6" : "ip";
|
||||
stream_filters << QString("(%1.src==%2 && udp.srcport==%3 && %1.dst==%4 && udp.dstport==%5 && rtp.ssrc==0x%6)")
|
||||
|
@ -611,7 +611,7 @@ void RtpStreamDialog::on_actionPrepareFilter_triggered()
|
|||
}
|
||||
if (stream_filters.length() > 0) {
|
||||
QString filter = stream_filters.join(" || ");
|
||||
remove_tap_listener_rtp_stream(&tapinfo_);
|
||||
remove_tap_listener_rtpstream(&tapinfo_);
|
||||
emit updateFilter(filter);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -179,7 +179,7 @@ void VoipCallsDialog::tapDraw(void *tapinfo_ptr)
|
|||
for (; graph_item; graph_item = g_list_next(graph_item)) {
|
||||
for (GList *rsi_entry = g_list_first(tapinfo->rtp_stream_list); rsi_entry; rsi_entry = g_list_next(rsi_entry)) {
|
||||
seq_analysis_item_t * sai = (seq_analysis_item_t *)graph_item->data;
|
||||
rtp_stream_info_t *rsi = (rtp_stream_info_t *)rsi_entry->data;
|
||||
rtpstream_info_t *rsi = (rtpstream_info_t *)rsi_entry->data;
|
||||
|
||||
if (rsi->start_fd->num == sai->frame_number) {
|
||||
rsi->call_num = sai->conv_num;
|
||||
|
@ -392,7 +392,7 @@ void VoipCallsDialog::showPlayer()
|
|||
if (!vci) continue;
|
||||
|
||||
for (GList *rsi_entry = g_list_first(tapinfo_.rtp_stream_list); rsi_entry; rsi_entry = g_list_next(rsi_entry)) {
|
||||
rtp_stream_info_t *rsi = (rtp_stream_info_t *)rsi_entry->data;
|
||||
rtpstream_info_t *rsi = (rtpstream_info_t *)rsi_entry->data;
|
||||
if (!rsi) continue;
|
||||
|
||||
//VOIP_CALLS_DEBUG("checking call %u, start frame %u == stream call %u, start frame %u, setup frame %u",
|
||||
|
|
|
@ -72,6 +72,7 @@ decode_rtp_packet(rtp_packet_t *rp, SAMPLE **out_buff, GHashTable *decoders_hash
|
|||
g_hash_table_insert(decoders_hash, GUINT_TO_POINTER(payload_type), decoder);
|
||||
}
|
||||
if (decoder->handle) { /* Decode with registered codec */
|
||||
/* if output == NULL and outputSizeBytes == NULL => ask for expected size of the buffer */
|
||||
tmp_buff_len = codec_decode(decoder->handle, decoder->context, rp->payload_data, rp->info->info_payload_len, NULL, NULL);
|
||||
tmp_buff = (SAMPLE *)g_malloc(tmp_buff_len);
|
||||
decoded_bytes = codec_decode(decoder->handle, decoder->context, rp->payload_data, rp->info->info_payload_len, tmp_buff, &tmp_buff_len);
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
|
||||
/****************************************************************************/
|
||||
/* redraw the output */
|
||||
static void rtpstream_draw(void *ti_ptr)
|
||||
static void rtpstream_draw_cb(void *ti_ptr)
|
||||
{
|
||||
rtpstream_tapinfo_t *tapinfo = (rtpstream_tapinfo_t *)ti_ptr;
|
||||
/* XXX: see rtpstream_on_update in rtp_streams_dlg.c for comments
|
||||
|
@ -59,20 +59,20 @@ void rtpstream_scan(rtpstream_tapinfo_t *tapinfo, capture_file *cap_file, const
|
|||
|
||||
was_registered = tapinfo->is_registered;
|
||||
if (!tapinfo->is_registered)
|
||||
register_tap_listener_rtp_stream(tapinfo, fstring);
|
||||
register_tap_listener_rtpstream(tapinfo, fstring);
|
||||
|
||||
/* RTP_STREAM_DEBUG("scanning %s, filter: %s", cap_file->filename, fstring); */
|
||||
tapinfo->mode = TAP_ANALYSE;
|
||||
cf_retap_packets(cap_file);
|
||||
|
||||
if (!was_registered)
|
||||
remove_tap_listener_rtp_stream(tapinfo);
|
||||
remove_tap_listener_rtpstream(tapinfo);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
/* save rtp dump of stream_fwd */
|
||||
gboolean rtpstream_save(rtpstream_tapinfo_t *tapinfo, capture_file *cap_file, rtp_stream_info_t* stream, const gchar *filename)
|
||||
gboolean rtpstream_save(rtpstream_tapinfo_t *tapinfo, capture_file *cap_file, rtpstream_info_t* stream, const gchar *filename)
|
||||
{
|
||||
gboolean was_registered;
|
||||
|
||||
|
@ -97,7 +97,7 @@ gboolean rtpstream_save(rtpstream_tapinfo_t *tapinfo, capture_file *cap_file, rt
|
|||
}
|
||||
|
||||
if (!tapinfo->is_registered)
|
||||
register_tap_listener_rtp_stream(tapinfo, NULL);
|
||||
register_tap_listener_rtpstream(tapinfo, NULL);
|
||||
|
||||
tapinfo->mode = TAP_SAVE;
|
||||
tapinfo->filter_stream_fwd = stream;
|
||||
|
@ -105,7 +105,7 @@ gboolean rtpstream_save(rtpstream_tapinfo_t *tapinfo, capture_file *cap_file, rt
|
|||
tapinfo->mode = TAP_ANALYSE;
|
||||
|
||||
if (!was_registered)
|
||||
remove_tap_listener_rtp_stream(tapinfo);
|
||||
remove_tap_listener_rtpstream(tapinfo);
|
||||
|
||||
if (ferror(tapinfo->save_file)) {
|
||||
write_failure_alert_box(filename, errno);
|
||||
|
@ -122,7 +122,7 @@ gboolean rtpstream_save(rtpstream_tapinfo_t *tapinfo, capture_file *cap_file, rt
|
|||
|
||||
/****************************************************************************/
|
||||
/* compare the endpoints of two RTP streams */
|
||||
gboolean rtp_stream_info_is_reverse(const rtp_stream_info_t *stream_a, rtp_stream_info_t *stream_b)
|
||||
gboolean rtpstream_info_is_reverse(const rtpstream_info_t *stream_a, rtpstream_info_t *stream_b)
|
||||
{
|
||||
if (stream_a == NULL || stream_b == NULL)
|
||||
return FALSE;
|
||||
|
@ -138,7 +138,7 @@ gboolean rtp_stream_info_is_reverse(const rtp_stream_info_t *stream_a, rtp_strea
|
|||
|
||||
/****************************************************************************/
|
||||
/* mark packets in stream_fwd or stream_rev */
|
||||
void rtpstream_mark(rtpstream_tapinfo_t *tapinfo, capture_file *cap_file, rtp_stream_info_t* stream_fwd, rtp_stream_info_t* stream_rev)
|
||||
void rtpstream_mark(rtpstream_tapinfo_t *tapinfo, capture_file *cap_file, rtpstream_info_t* stream_fwd, rtpstream_info_t* stream_rev)
|
||||
{
|
||||
gboolean was_registered;
|
||||
|
||||
|
@ -149,7 +149,7 @@ void rtpstream_mark(rtpstream_tapinfo_t *tapinfo, capture_file *cap_file, rtp_st
|
|||
was_registered = tapinfo->is_registered;
|
||||
|
||||
if (!tapinfo->is_registered)
|
||||
register_tap_listener_rtp_stream(tapinfo, NULL);
|
||||
register_tap_listener_rtpstream(tapinfo, NULL);
|
||||
|
||||
tapinfo->mode = TAP_MARK;
|
||||
tapinfo->filter_stream_fwd = stream_fwd;
|
||||
|
@ -158,7 +158,7 @@ void rtpstream_mark(rtpstream_tapinfo_t *tapinfo, capture_file *cap_file, rtp_st
|
|||
tapinfo->mode = TAP_ANALYSE;
|
||||
|
||||
if (!was_registered)
|
||||
remove_tap_listener_rtp_stream(tapinfo);
|
||||
remove_tap_listener_rtpstream(tapinfo);
|
||||
}
|
||||
|
||||
|
||||
|
@ -168,7 +168,7 @@ void rtpstream_mark(rtpstream_tapinfo_t *tapinfo, capture_file *cap_file, rtp_st
|
|||
|
||||
/****************************************************************************/
|
||||
void
|
||||
remove_tap_listener_rtp_stream(rtpstream_tapinfo_t *tapinfo)
|
||||
remove_tap_listener_rtpstream(rtpstream_tapinfo_t *tapinfo)
|
||||
{
|
||||
if (tapinfo && tapinfo->is_registered) {
|
||||
remove_tap_listener(tapinfo);
|
||||
|
@ -179,7 +179,7 @@ remove_tap_listener_rtp_stream(rtpstream_tapinfo_t *tapinfo)
|
|||
|
||||
/****************************************************************************/
|
||||
void
|
||||
register_tap_listener_rtp_stream(rtpstream_tapinfo_t *tapinfo, const char *fstring)
|
||||
register_tap_listener_rtpstream(rtpstream_tapinfo_t *tapinfo, const char *fstring)
|
||||
{
|
||||
GString *error_string;
|
||||
|
||||
|
@ -189,8 +189,8 @@ register_tap_listener_rtp_stream(rtpstream_tapinfo_t *tapinfo, const char *fstri
|
|||
|
||||
if (!tapinfo->is_registered) {
|
||||
error_string = register_tap_listener("rtp", tapinfo,
|
||||
fstring, 0, rtpstream_reset_cb, rtpstream_packet,
|
||||
rtpstream_draw);
|
||||
fstring, 0, rtpstream_reset_cb, rtpstream_packet_cb,
|
||||
rtpstream_draw_cb);
|
||||
|
||||
if (error_string != NULL) {
|
||||
simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
|
||||
|
|
|
@ -33,7 +33,7 @@ extern "C" {
|
|||
#include <epan/tap.h>
|
||||
|
||||
/** Defines an rtp stream */
|
||||
typedef struct _rtp_stream_info {
|
||||
typedef struct _rtpstream_info {
|
||||
address src_addr;
|
||||
guint32 src_port;
|
||||
address dest_addr;
|
||||
|
@ -62,7 +62,7 @@ typedef struct _rtp_stream_info {
|
|||
tap_rtp_stat_t rtp_stats; /**< here goes the RTP statistics info */
|
||||
gboolean problem; /**< if the streams had wrong sequence numbers or wrong timestamps */
|
||||
gchar *ed137_info;
|
||||
} rtp_stream_info_t;
|
||||
} rtpstream_info_t;
|
||||
|
||||
/** tapping modes */
|
||||
typedef enum
|
||||
|
@ -90,8 +90,8 @@ struct _rtpstream_tapinfo {
|
|||
int npackets; /**< total number of rtp packets of all streams */
|
||||
/* used while tapping. user shouldn't modify these */
|
||||
tap_mode_t mode;
|
||||
rtp_stream_info_t *filter_stream_fwd; /**< used as filter in some tap modes */
|
||||
rtp_stream_info_t *filter_stream_rev; /**< used as filter in some tap modes */
|
||||
rtpstream_info_t *filter_stream_fwd; /**< used as filter in some tap modes */
|
||||
rtpstream_info_t *filter_stream_rev; /**< used as filter in some tap modes */
|
||||
FILE *save_file;
|
||||
gboolean is_registered; /**< if the tap listener is currently registered or not */
|
||||
};
|
||||
|
@ -116,13 +116,13 @@ struct _rtpstream_tapinfo {
|
|||
* So whenever rtp_stream.c is added to the list of WIRESHARK_TAP_SRCs, the tap will be registered on startup.
|
||||
* If not, it will be registered on demand by the rtp_streams and rtp_analysis functions that need it.
|
||||
*/
|
||||
void register_tap_listener_rtp_stream(rtpstream_tapinfo_t *tapinfo, const char *fstring);
|
||||
void register_tap_listener_rtpstream(rtpstream_tapinfo_t *tapinfo, const char *fstring);
|
||||
|
||||
/**
|
||||
* Removes the rtp_streams tap listener (if not already done)
|
||||
* From that point on, the RTP streams list won't be updated any more.
|
||||
*/
|
||||
void remove_tap_listener_rtp_stream(rtpstream_tapinfo_t *tapinfo);
|
||||
void remove_tap_listener_rtpstream(rtpstream_tapinfo_t *tapinfo);
|
||||
|
||||
/**
|
||||
* Cleans up memory of rtp streams tap.
|
||||
|
@ -139,21 +139,21 @@ void rtpstream_scan(rtpstream_tapinfo_t *tapinfo, capture_file *cap_file, const
|
|||
* Saves an RTP stream as raw data stream with timestamp information for later RTP playback.
|
||||
* (redissects all packets)
|
||||
*/
|
||||
gboolean rtpstream_save(rtpstream_tapinfo_t *tapinfo, capture_file *cap_file, rtp_stream_info_t* stream, const gchar *filename);
|
||||
gboolean rtpstream_save(rtpstream_tapinfo_t *tapinfo, capture_file *cap_file, rtpstream_info_t* stream, const gchar *filename);
|
||||
|
||||
/**
|
||||
* Compares the endpoints of two RTP streams.
|
||||
*
|
||||
* @return TRUE if the
|
||||
*/
|
||||
gboolean rtp_stream_info_is_reverse(const rtp_stream_info_t *stream_a, rtp_stream_info_t *stream_b);
|
||||
gboolean rtpstream_info_is_reverse(const rtpstream_info_t *stream_a, rtpstream_info_t *stream_b);
|
||||
|
||||
/**
|
||||
* Marks all packets belonging to either of stream_fwd or stream_rev.
|
||||
* (both can be NULL)
|
||||
* (redissects all packets)
|
||||
*/
|
||||
void rtpstream_mark(rtpstream_tapinfo_t *tapinfo, capture_file *cap_file, rtp_stream_info_t* stream_fwd, rtp_stream_info_t* stream_rev);
|
||||
void rtpstream_mark(rtpstream_tapinfo_t *tapinfo, capture_file *cap_file, rtpstream_info_t* stream_fwd, rtpstream_info_t* stream_rev);
|
||||
|
||||
#define MAX_SILENCE_FRAMES 14400000
|
||||
|
||||
|
|
|
@ -41,10 +41,10 @@ typedef struct _iax2_bw_history_item {
|
|||
#define BUFF_BW 300
|
||||
|
||||
typedef struct _tap_iax2_stat_t {
|
||||
gboolean first_packet; /* do not use in code that is called after rtp_packet_analyse */
|
||||
gboolean first_packet; /* do not use in code that is called after iax2_packet_analyse */
|
||||
/* use (flags & STAT_FLAG_FIRST) instead */
|
||||
/* all of the following fields will be initialized after
|
||||
rtp_packet_analyse has been called */
|
||||
iax2_packet_analyse has been called */
|
||||
guint32 flags; /* see STAT_FLAG-defines below */
|
||||
guint16 seq_num;
|
||||
guint32 timestamp;
|
||||
|
|
|
@ -0,0 +1,479 @@
|
|||
/* tap-rtp-analysis.c
|
||||
* RTP stream handler functions used by tshark and wireshark
|
||||
*
|
||||
* Copyright 2008, Ericsson AB
|
||||
* By Balint Reczey <balint.reczey@ericsson.com>
|
||||
*
|
||||
* most functions are copied from ui/gtk/rtp_stream.c and ui/gtk/rtp_analysis.c
|
||||
* Copyright 2003, Alcatel Business Systems
|
||||
* By Lars Ruoff <lars.ruoff@gmx.net>
|
||||
*
|
||||
* Wireshark - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@wireshark.org>
|
||||
* Copyright 1998 Gerald Combs
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include <math.h>
|
||||
#include "globals.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <epan/rtp_pt.h>
|
||||
#include <epan/addr_resolv.h>
|
||||
#include <epan/proto_data.h>
|
||||
#include <epan/dissectors/packet-rtp.h>
|
||||
#include <wsutil/pint.h>
|
||||
#include "rtp_stream.h"
|
||||
#include "tap-rtp-common.h"
|
||||
#include "tap-rtp-analysis.h"
|
||||
|
||||
typedef struct _key_value {
|
||||
guint32 key;
|
||||
guint32 value;
|
||||
} key_value;
|
||||
|
||||
|
||||
/* RTP sampling clock rates for fixed payload types as defined in
|
||||
http://www.iana.org/assignments/rtp-parameters */
|
||||
static const key_value clock_map[] = {
|
||||
{PT_PCMU, 8000},
|
||||
{PT_1016, 8000},
|
||||
{PT_G721, 8000},
|
||||
{PT_GSM, 8000},
|
||||
{PT_G723, 8000},
|
||||
{PT_DVI4_8000, 8000},
|
||||
{PT_DVI4_16000, 16000},
|
||||
{PT_LPC, 8000},
|
||||
{PT_PCMA, 8000},
|
||||
{PT_G722, 8000},
|
||||
{PT_L16_STEREO, 44100},
|
||||
{PT_L16_MONO, 44100},
|
||||
{PT_QCELP, 8000},
|
||||
{PT_CN, 8000},
|
||||
{PT_MPA, 90000},
|
||||
{PT_G728, 8000},
|
||||
{PT_G728, 8000},
|
||||
{PT_DVI4_11025, 11025},
|
||||
{PT_DVI4_22050, 22050},
|
||||
{PT_G729, 8000},
|
||||
{PT_CN_OLD, 8000},
|
||||
{PT_CELB, 90000},
|
||||
{PT_JPEG, 90000},
|
||||
{PT_NV, 90000},
|
||||
{PT_H261, 90000},
|
||||
{PT_MPV, 90000},
|
||||
{PT_MP2T, 90000},
|
||||
{PT_H263, 90000},
|
||||
};
|
||||
|
||||
#define NUM_CLOCK_VALUES (sizeof clock_map / sizeof clock_map[0])
|
||||
|
||||
static guint32
|
||||
get_clock_rate(guint32 key)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < NUM_CLOCK_VALUES; i++) {
|
||||
if (clock_map[i].key == key)
|
||||
return clock_map[i].value;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
typedef struct _mimetype_and_clock {
|
||||
const gchar *pt_mime_name_str;
|
||||
guint32 value;
|
||||
} mimetype_and_clock;
|
||||
/* RTP sampling clock rates for
|
||||
"In addition to the RTP payload formats (encodings) listed in the RTP
|
||||
Payload Types table, there are additional payload formats that do not
|
||||
have static RTP payload types assigned but instead use dynamic payload
|
||||
type number assignment. Each payload format is named by a registered
|
||||
MIME subtype"
|
||||
http://www.iana.org/assignments/rtp-parameters.
|
||||
|
||||
NOTE: Please keep the mimetypes in case insensitive alphabetical order.
|
||||
*/
|
||||
static const mimetype_and_clock mimetype_and_clock_map[] = {
|
||||
{"AMR", 8000}, /* [RFC4867][RFC3267] */
|
||||
{"AMR-WB", 16000}, /* [RFC4867][RFC3267] */
|
||||
{"BMPEG", 90000}, /* [RFC2343],[RFC3555] */
|
||||
{"BT656", 90000}, /* [RFC2431],[RFC3555] */
|
||||
{"DV", 90000}, /* [RFC3189] */
|
||||
{"EVRC", 8000}, /* [RFC3558] */
|
||||
{"EVRC0", 8000}, /* [RFC4788] */
|
||||
{"EVRC1", 8000}, /* [RFC4788] */
|
||||
{"EVRCB", 8000}, /* [RFC4788] */
|
||||
{"EVRCB0", 8000}, /* [RFC4788] */
|
||||
{"EVRCB1", 8000}, /* [RFC4788] */
|
||||
{"EVRCWB", 16000}, /* [RFC5188] */
|
||||
{"EVRCWB0", 16000}, /* [RFC5188] */
|
||||
{"EVRCWB1", 16000}, /* [RFC5188] */
|
||||
{"EVS", 16000}, /* [3GPP TS 26.445] */
|
||||
{"G7221", 16000}, /* [RFC3047] */
|
||||
{"G726-16", 8000}, /* [RFC3551][RFC4856] */
|
||||
{"G726-24", 8000}, /* [RFC3551][RFC4856] */
|
||||
{"G726-32", 8000}, /* [RFC3551][RFC4856] */
|
||||
{"G726-40", 8000}, /* [RFC3551][RFC4856] */
|
||||
{"G729D", 8000}, /* [RFC3551][RFC4856] */
|
||||
{"G729E", 8000}, /* [RFC3551][RFC4856] */
|
||||
{"GSM-EFR", 8000}, /* [RFC3551] */
|
||||
{"H263-1998", 90000}, /* [RFC2429],[RFC3555] */
|
||||
{"H263-2000", 90000}, /* [RFC2429],[RFC3555] */
|
||||
{"H264", 90000}, /* [RFC3984] */
|
||||
{"MP1S", 90000}, /* [RFC2250],[RFC3555] */
|
||||
{"MP2P", 90000}, /* [RFC2250],[RFC3555] */
|
||||
{"MP4V-ES", 90000}, /* [RFC3016] */
|
||||
{"mpa-robust", 90000}, /* [RFC3119] */
|
||||
{"pointer", 90000}, /* [RFC2862] */
|
||||
{"raw", 90000}, /* [RFC4175] */
|
||||
{"red", 1000}, /* [RFC4102] */
|
||||
{"SMV", 8000}, /* [RFC3558] */
|
||||
{"SMV0", 8000}, /* [RFC3558] */
|
||||
{"t140", 1000}, /* [RFC4103] */
|
||||
{"telephone-event", 8000}, /* [RFC4733] */
|
||||
};
|
||||
|
||||
#define NUM_DYN_CLOCK_VALUES (sizeof mimetype_and_clock_map / sizeof mimetype_and_clock_map[0])
|
||||
|
||||
static guint32
|
||||
get_dyn_pt_clock_rate(const gchar *payload_type_str)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Search for matching mimetype in reverse order to avoid false matches
|
||||
* when pt_mime_name_str is the prefix of payload_type_str */
|
||||
for (i = NUM_DYN_CLOCK_VALUES - 1; i > -1 ; i--) {
|
||||
if (g_ascii_strncasecmp(mimetype_and_clock_map[i].pt_mime_name_str,payload_type_str,(strlen(mimetype_and_clock_map[i].pt_mime_name_str))) == 0)
|
||||
return mimetype_and_clock_map[i].value;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
void
|
||||
rtppacket_analyse(tap_rtp_stat_t *statinfo,
|
||||
packet_info *pinfo,
|
||||
const struct _rtp_info *rtpinfo)
|
||||
{
|
||||
double current_time;
|
||||
double current_jitter;
|
||||
double current_diff = 0;
|
||||
double nominaltime;
|
||||
double arrivaltime; /* Time relative to start_time */
|
||||
double expected_time;
|
||||
double absskew;
|
||||
guint32 clock_rate;
|
||||
|
||||
/* Store the current time */
|
||||
current_time = nstime_to_msec(&pinfo->rel_ts);
|
||||
|
||||
/* Is this the first packet we got in this direction? */
|
||||
if (statinfo->first_packet) {
|
||||
/* Save the MAC address of the first RTP frame */
|
||||
if( pinfo->dl_src.type == AT_ETHER){
|
||||
copy_address(&(statinfo->first_packet_mac_addr), &(pinfo->dl_src));
|
||||
}
|
||||
statinfo->start_seq_nr = rtpinfo->info_seq_num;
|
||||
statinfo->stop_seq_nr = rtpinfo->info_seq_num;
|
||||
statinfo->seq_num = rtpinfo->info_seq_num;
|
||||
statinfo->start_time = current_time;
|
||||
statinfo->timestamp = rtpinfo->info_timestamp;
|
||||
statinfo->first_timestamp = rtpinfo->info_timestamp;
|
||||
statinfo->time = current_time;
|
||||
statinfo->lastnominaltime = 0;
|
||||
statinfo->pt = rtpinfo->info_payload_type;
|
||||
statinfo->reg_pt = rtpinfo->info_payload_type;
|
||||
if (pinfo->net_src.type == AT_IPv6) {
|
||||
statinfo->bw_history[statinfo->bw_index].bytes = rtpinfo->info_data_len + 48;
|
||||
} else {
|
||||
statinfo->bw_history[statinfo->bw_index].bytes = rtpinfo->info_data_len + 28;
|
||||
}
|
||||
statinfo->bw_history[statinfo->bw_index].time = current_time;
|
||||
statinfo->bw_index++;
|
||||
if (pinfo->net_src.type == AT_IPv6) {
|
||||
statinfo->total_bytes += rtpinfo->info_data_len + 48;
|
||||
} else {
|
||||
statinfo->total_bytes += rtpinfo->info_data_len + 28;
|
||||
}
|
||||
statinfo->bandwidth = (double)(statinfo->total_bytes*8)/1000;
|
||||
/* Not needed ? initialised to zero? */
|
||||
statinfo->delta = 0;
|
||||
statinfo->jitter = 0;
|
||||
statinfo->diff = 0;
|
||||
|
||||
statinfo->total_nr++;
|
||||
statinfo->flags |= STAT_FLAG_FIRST;
|
||||
if (rtpinfo->info_marker_set) {
|
||||
statinfo->flags |= STAT_FLAG_MARKER;
|
||||
}
|
||||
statinfo->first_packet_num = pinfo->num;
|
||||
statinfo->first_packet = FALSE;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Reset flags */
|
||||
statinfo->flags = 0;
|
||||
#if 0
|
||||
/*According to bug https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=11478
|
||||
* this code causes problems. A better solution is needed if there is need for the functionality */
|
||||
/* Try to detect duplicated packets due to mirroring/span ports by comparing src MAC addresses.
|
||||
* Check for duplicates (src mac differs from first_packet_mac_addr) */
|
||||
*/
|
||||
if( pinfo->dl_src.type == AT_ETHER){
|
||||
if(!addresses_equal(&(statinfo->first_packet_mac_addr), &(pinfo->dl_src))){
|
||||
statinfo->flags |= STAT_FLAG_DUP_PKT;
|
||||
statinfo->delta = current_time-(statinfo->time);
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/* When calculating expected rtp packets the seq number can wrap around
|
||||
* so we have to count the number of cycles
|
||||
* Variable cycles counts the wraps around in forwarding connection and
|
||||
* under is flag that indicates where we are
|
||||
*
|
||||
* XXX How to determine number of cycles with all possible lost, late
|
||||
* and duplicated packets without any doubt? It seems to me, that
|
||||
* because of all possible combination of late, duplicated or lost
|
||||
* packets, this can only be more or less good approximation
|
||||
*
|
||||
* There are some combinations (rare but theoretically possible),
|
||||
* where below code won't work correctly - statistic may be wrong then.
|
||||
*/
|
||||
|
||||
/* So if the current sequence number is less than the start one
|
||||
* we assume, that there is another cycle running
|
||||
*/
|
||||
if ((rtpinfo->info_seq_num < statinfo->start_seq_nr) && (statinfo->under == FALSE)){
|
||||
statinfo->cycles++;
|
||||
statinfo->under = TRUE;
|
||||
}
|
||||
/* what if the start seq nr was 0? Then the above condition will never
|
||||
* be true, so we add another condition. XXX The problem would arise
|
||||
* if one of the packets with seq nr 0 or 65535 would be lost or late
|
||||
*/
|
||||
else if ((rtpinfo->info_seq_num == 0) && (statinfo->stop_seq_nr == 65535) &&
|
||||
(statinfo->under == FALSE)) {
|
||||
statinfo->cycles++;
|
||||
statinfo->under = TRUE;
|
||||
}
|
||||
/* the whole round is over, so reset the flag */
|
||||
else if ((rtpinfo->info_seq_num > statinfo->start_seq_nr) && (statinfo->under != FALSE)) {
|
||||
statinfo->under = FALSE;
|
||||
}
|
||||
|
||||
/* Since it is difficult to count lost, duplicate or late packets separately,
|
||||
* we would like to know at least how many times the sequence number was not ok
|
||||
*/
|
||||
|
||||
/* If the current seq number equals the last one or if we are here for
|
||||
* the first time, then it is ok, we just store the current one as the last one
|
||||
*/
|
||||
if ( (statinfo->seq_num+1 == rtpinfo->info_seq_num) || (statinfo->flags & STAT_FLAG_FIRST) )
|
||||
statinfo->seq_num = rtpinfo->info_seq_num;
|
||||
/* If the first one is 65535 we wrap */
|
||||
else if ( (statinfo->seq_num == 65535) && (rtpinfo->info_seq_num == 0) )
|
||||
statinfo->seq_num = rtpinfo->info_seq_num;
|
||||
/* Lost packets. If the prev seq is enormously larger than the cur seq
|
||||
* we assume that instead of being massively late we lost the packet(s)
|
||||
* that would have indicated the sequence number wrapping. An imprecise
|
||||
* heuristic at best, but it seems to work well enough.
|
||||
* https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=5958 */
|
||||
else if (statinfo->seq_num+1 < rtpinfo->info_seq_num || statinfo->seq_num - rtpinfo->info_seq_num > 0xFF00) {
|
||||
statinfo->seq_num = rtpinfo->info_seq_num;
|
||||
statinfo->sequence++;
|
||||
statinfo->flags |= STAT_FLAG_WRONG_SEQ;
|
||||
}
|
||||
/* Late or duplicated */
|
||||
else if (statinfo->seq_num+1 > rtpinfo->info_seq_num) {
|
||||
statinfo->sequence++;
|
||||
statinfo->flags |= STAT_FLAG_WRONG_SEQ;
|
||||
}
|
||||
|
||||
/* Check payload type */
|
||||
if (rtpinfo->info_payload_type == PT_CN
|
||||
|| rtpinfo->info_payload_type == PT_CN_OLD)
|
||||
statinfo->flags |= STAT_FLAG_PT_CN;
|
||||
if (statinfo->pt == PT_CN
|
||||
|| statinfo->pt == PT_CN_OLD)
|
||||
statinfo->flags |= STAT_FLAG_FOLLOW_PT_CN;
|
||||
if (rtpinfo->info_payload_type != statinfo->pt)
|
||||
statinfo->flags |= STAT_FLAG_PT_CHANGE;
|
||||
statinfo->pt = rtpinfo->info_payload_type;
|
||||
|
||||
/*
|
||||
* Return for unknown payload types
|
||||
* Ignore jitter calculation for clockrate = 0
|
||||
*/
|
||||
if (statinfo->pt < 96 ){
|
||||
clock_rate = get_clock_rate(statinfo->pt);
|
||||
} else { /* Dynamic PT */
|
||||
if ( rtpinfo->info_payload_type_str != NULL ) {
|
||||
/* Is it a "telephone-event" ?
|
||||
* Timestamp is not increased for telepone-event packets impacting
|
||||
* calculation of Jitter Skew and clock drift.
|
||||
* see 2.2.1 of RFC 4733
|
||||
*/
|
||||
if (g_ascii_strncasecmp("telephone-event",rtpinfo->info_payload_type_str,(strlen("telephone-event")))==0) {
|
||||
clock_rate = 0;
|
||||
statinfo->flags |= STAT_FLAG_PT_T_EVENT;
|
||||
} else {
|
||||
if(rtpinfo->info_payload_rate !=0) {
|
||||
clock_rate = rtpinfo->info_payload_rate;
|
||||
} else {
|
||||
clock_rate = get_dyn_pt_clock_rate(rtpinfo->info_payload_type_str);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
clock_rate = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Handle wraparound ? */
|
||||
arrivaltime = current_time - statinfo->start_time;
|
||||
|
||||
nominaltime = (double)(guint32_wraparound_diff(rtpinfo->info_timestamp, statinfo->first_timestamp));
|
||||
|
||||
/* Can only analyze defined sampling rates */
|
||||
if (clock_rate != 0) {
|
||||
statinfo->clock_rate = clock_rate;
|
||||
/* Convert from sampling clock to ms */
|
||||
nominaltime = nominaltime /(clock_rate/1000);
|
||||
|
||||
/* Calculate the current jitter(in ms) */
|
||||
if (!statinfo->first_packet) {
|
||||
expected_time = statinfo->time + (nominaltime - statinfo->lastnominaltime);
|
||||
current_diff = fabs(current_time - expected_time);
|
||||
current_jitter = (15 * statinfo->jitter + current_diff) / 16;
|
||||
|
||||
statinfo->delta = current_time-(statinfo->time);
|
||||
statinfo->jitter = current_jitter;
|
||||
statinfo->diff = current_diff;
|
||||
}
|
||||
statinfo->lastnominaltime = nominaltime;
|
||||
/* Calculate skew, i.e. absolute jitter that also catches clock drift
|
||||
* Skew is positive if TS (nominal) is too fast
|
||||
*/
|
||||
statinfo->skew = nominaltime - arrivaltime;
|
||||
absskew = fabs(statinfo->skew);
|
||||
if(absskew > fabs(statinfo->max_skew)) {
|
||||
statinfo->max_skew = statinfo->skew;
|
||||
}
|
||||
/* Gather data for calculation of average, minimum and maximum framerate based on timestamp */
|
||||
#if 0
|
||||
if (numPackets > 0 && (!hardPayloadType || !alternatePayloadType)) {
|
||||
/* Skip first packet and possibly alternate payload type packets */
|
||||
double dt;
|
||||
dt = nominaltime - statinfo->lastnominaltime;
|
||||
sumdt += 1.0 * dt;
|
||||
numdt += (dt != 0 ? 1 : 0);
|
||||
mindt = (dt < mindt ? dt : mindt);
|
||||
maxdt = (dt > maxdt ? dt : maxdt);
|
||||
}
|
||||
#endif
|
||||
/* Gather data for calculation of skew least square */
|
||||
statinfo->sumt += 1.0 * current_time;
|
||||
statinfo->sumTS += 1.0 * nominaltime;
|
||||
statinfo->sumt2 += 1.0 * current_time * current_time;
|
||||
statinfo->sumtTS += 1.0 * current_time * nominaltime;
|
||||
}
|
||||
|
||||
/* Calculate the BW in Kbps adding the IP+UDP header to the RTP -> 20bytes(IP) + 8bytes(UDP) */
|
||||
if (pinfo->net_src.type == AT_IPv6) {
|
||||
statinfo->bw_history[statinfo->bw_index].bytes = rtpinfo->info_data_len + 48;
|
||||
} else {
|
||||
statinfo->bw_history[statinfo->bw_index].bytes = rtpinfo->info_data_len + 28;
|
||||
}
|
||||
statinfo->bw_history[statinfo->bw_index].time = current_time;
|
||||
|
||||
/* Check if there are more than 1sec in the history buffer to calculate BW in bps. If so, remove those for the calculation */
|
||||
while ((statinfo->bw_history[statinfo->bw_start_index].time+1000/* ms */)<current_time){
|
||||
statinfo->total_bytes -= statinfo->bw_history[statinfo->bw_start_index].bytes;
|
||||
statinfo->bw_start_index++;
|
||||
if (statinfo->bw_start_index == BUFF_BW) statinfo->bw_start_index=0;
|
||||
};
|
||||
/* IP hdr + UDP + RTP */
|
||||
if (pinfo->net_src.type == AT_IPv6){
|
||||
statinfo->total_bytes += rtpinfo->info_data_len + 48;
|
||||
}else{
|
||||
statinfo->total_bytes += rtpinfo->info_data_len + 28;
|
||||
}
|
||||
statinfo->bandwidth = (double)(statinfo->total_bytes*8)/1000;
|
||||
statinfo->bw_index++;
|
||||
if (statinfo->bw_index == BUFF_BW) statinfo->bw_index = 0;
|
||||
|
||||
|
||||
/* Used by GTK code only */
|
||||
statinfo->delta_timestamp = guint32_wraparound_diff(rtpinfo->info_timestamp, statinfo->timestamp);
|
||||
|
||||
/* Is it a packet with the mark bit set? */
|
||||
if (rtpinfo->info_marker_set) {
|
||||
statinfo->flags |= STAT_FLAG_MARKER;
|
||||
}
|
||||
|
||||
/* Difference can be negative. We don't expect difference bigger than 31 bits. Difference don't care about wrap around. */
|
||||
gint32 tsdelta=rtpinfo->info_timestamp - statinfo->timestamp;
|
||||
if (tsdelta < 0) {
|
||||
statinfo->flags |= STAT_FLAG_WRONG_TIMESTAMP;
|
||||
}
|
||||
/* Is it a regular packet? */
|
||||
if (!(statinfo->flags & STAT_FLAG_FIRST)
|
||||
&& !(statinfo->flags & STAT_FLAG_MARKER)
|
||||
&& !(statinfo->flags & STAT_FLAG_PT_CN)
|
||||
&& !(statinfo->flags & STAT_FLAG_WRONG_TIMESTAMP)
|
||||
&& !(statinfo->flags & STAT_FLAG_FOLLOW_PT_CN)) {
|
||||
/* Include it in maximum delta calculation */
|
||||
if (statinfo->delta > statinfo->max_delta) {
|
||||
statinfo->max_delta = statinfo->delta;
|
||||
statinfo->max_nr = pinfo->num;
|
||||
}
|
||||
if (clock_rate != 0) {
|
||||
/* Maximum and mean jitter calculation */
|
||||
if (statinfo->jitter > statinfo->max_jitter) {
|
||||
statinfo->max_jitter = statinfo->jitter;
|
||||
}
|
||||
statinfo->mean_jitter = (statinfo->mean_jitter*statinfo->total_nr + current_diff) / (statinfo->total_nr+1);
|
||||
}
|
||||
}
|
||||
/* Regular payload change? (CN ignored) */
|
||||
if (!(statinfo->flags & STAT_FLAG_FIRST)
|
||||
&& !(statinfo->flags & STAT_FLAG_PT_CN)) {
|
||||
if ((statinfo->pt != statinfo->reg_pt)
|
||||
&& (statinfo->reg_pt != PT_UNDEFINED)) {
|
||||
statinfo->flags |= STAT_FLAG_REG_PT_CHANGE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set regular payload*/
|
||||
if (!(statinfo->flags & STAT_FLAG_PT_CN)) {
|
||||
statinfo->reg_pt = statinfo->pt;
|
||||
}
|
||||
|
||||
statinfo->time = current_time;
|
||||
statinfo->timestamp = rtpinfo->info_timestamp;
|
||||
statinfo->stop_seq_nr = rtpinfo->info_seq_num;
|
||||
statinfo->total_nr++;
|
||||
statinfo->last_payload_len = rtpinfo->info_payload_len - rtpinfo->info_padding_count;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Editor modelines - https://www.wireshark.org/tools/modelines.html
|
||||
*
|
||||
* Local Variables:
|
||||
* c-basic-offset: 4
|
||||
* tab-width: 8
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*
|
||||
* ex: set shiftwidth=4 tabstop=8 expandtab:
|
||||
* :indentSize=4:tabSize=8:noTabs=true:
|
||||
*/
|
|
@ -53,10 +53,10 @@ typedef struct _bw_history_item {
|
|||
#define BUFF_BW 300
|
||||
|
||||
typedef struct _tap_rtp_stat_t {
|
||||
gboolean first_packet; /**< do not use in code that is called after rtp_packet_analyse */
|
||||
gboolean first_packet; /**< do not use in code that is called after rtppacket_analyse */
|
||||
/* use (flags & STAT_FLAG_FIRST) instead */
|
||||
/* all of the following fields will be initialized after
|
||||
* rtp_packet_analyse has been called
|
||||
* rtppacket_analyse has been called
|
||||
*/
|
||||
address first_packet_mac_addr; /**< MAC address of first packet, used to determine duplicates due to mirroring */
|
||||
guint32 flags; /* see STAT_FLAG-defines below */
|
||||
|
@ -122,7 +122,7 @@ typedef struct _tap_rtp_save_data_t {
|
|||
struct _rtp_info;
|
||||
|
||||
/* function for analysing an RTP packet. Called from rtp_analysis and rtp_streams */
|
||||
extern void rtp_packet_analyse(tap_rtp_stat_t *statinfo,
|
||||
extern void rtppacket_analyse(tap_rtp_stat_t *statinfo,
|
||||
packet_info *pinfo,
|
||||
const struct _rtp_info *rtpinfo);
|
||||
|
||||
|
|
|
@ -44,11 +44,11 @@ typedef struct st_rtpdump_info {
|
|||
} rtpdump_info_t;
|
||||
|
||||
/****************************************************************************/
|
||||
/* GCompareFunc style comparison function for _rtp_stream_info */
|
||||
static gint rtp_stream_info_cmp(gconstpointer aa, gconstpointer bb)
|
||||
/* GCompareFunc style comparison function for rtp_stream_info_t */
|
||||
static gint rtpstream_info_cmp(gconstpointer aa, gconstpointer bb)
|
||||
{
|
||||
const struct _rtp_stream_info* a = (const struct _rtp_stream_info*)aa;
|
||||
const struct _rtp_stream_info* b = (const struct _rtp_stream_info*)bb;
|
||||
const rtpstream_info_t* a = (const rtpstream_info_t*)aa;
|
||||
const rtpstream_info_t* b = (const rtpstream_info_t*)bb;
|
||||
|
||||
if (a==b)
|
||||
return 0;
|
||||
|
@ -122,7 +122,7 @@ void rtpstream_reset_cb(void *arg)
|
|||
* The header consists of an identifying string, followed
|
||||
* by a binary structure.
|
||||
*/
|
||||
void rtp_write_header(rtp_stream_info_t *strinfo, FILE *file)
|
||||
void rtp_write_header(rtpstream_info_t *strinfo, FILE *file)
|
||||
{
|
||||
guint32 start_sec; /* start of recording (GMT) (seconds) */
|
||||
guint32 start_usec; /* start of recording (GMT) (microseconds)*/
|
||||
|
@ -185,12 +185,12 @@ static void rtp_write_sample(rtpdump_info_t* rtpdump_info, FILE* file)
|
|||
|
||||
/****************************************************************************/
|
||||
/* whenever a RTP packet is seen by the tap listener */
|
||||
int rtpstream_packet(void *arg, packet_info *pinfo, epan_dissect_t *edt _U_, const void *arg2)
|
||||
int rtpstream_packet_cb(void *arg, packet_info *pinfo, epan_dissect_t *edt _U_, const void *arg2)
|
||||
{
|
||||
rtpstream_tapinfo_t *tapinfo = (rtpstream_tapinfo_t *)arg;
|
||||
const struct _rtp_info *rtpinfo = (const struct _rtp_info *)arg2;
|
||||
rtp_stream_info_t new_stream_info;
|
||||
rtp_stream_info_t *stream_info = NULL;
|
||||
rtpstream_info_t new_stream_info;
|
||||
rtpstream_info_t *stream_info = NULL;
|
||||
GList* list;
|
||||
rtpdump_info_t rtpdump_info;
|
||||
|
||||
|
@ -198,7 +198,7 @@ int rtpstream_packet(void *arg, packet_info *pinfo, epan_dissect_t *edt _U_, con
|
|||
|
||||
/* gather infos on the stream this packet is part of.
|
||||
* Addresses and strings are read-only and must be duplicated if copied. */
|
||||
memset(&new_stream_info, 0, sizeof(rtp_stream_info_t));
|
||||
memset(&new_stream_info, 0, sizeof(rtpstream_info_t));
|
||||
copy_address_shallow(&(new_stream_info.src_addr), &(pinfo->src));
|
||||
new_stream_info.src_port = pinfo->srcport;
|
||||
copy_address_shallow(&(new_stream_info.dest_addr), &(pinfo->dst));
|
||||
|
@ -212,9 +212,9 @@ int rtpstream_packet(void *arg, packet_info *pinfo, epan_dissect_t *edt _U_, con
|
|||
list = g_list_first(tapinfo->strinfo_list);
|
||||
while (list)
|
||||
{
|
||||
if (rtp_stream_info_cmp(&new_stream_info, (rtp_stream_info_t*)(list->data))==0)
|
||||
if (rtpstream_info_cmp(&new_stream_info, (rtpstream_info_t*)(list->data))==0)
|
||||
{
|
||||
stream_info = (rtp_stream_info_t*)(list->data); /*found!*/
|
||||
stream_info = (rtpstream_info_t*)(list->data); /*found!*/
|
||||
break;
|
||||
}
|
||||
list = g_list_next(list);
|
||||
|
@ -236,7 +236,7 @@ int rtpstream_packet(void *arg, packet_info *pinfo, epan_dissect_t *edt _U_, con
|
|||
else
|
||||
new_stream_info.setup_frame_number = 0xFFFFFFFF;
|
||||
|
||||
stream_info = g_new(rtp_stream_info_t,1);
|
||||
stream_info = g_new(rtpstream_info_t,1);
|
||||
/* Deep clone of contents. */
|
||||
copy_address(&(new_stream_info.src_addr), &(new_stream_info.src_addr));
|
||||
copy_address(&(new_stream_info.dest_addr), &(new_stream_info.dest_addr));
|
||||
|
@ -246,7 +246,7 @@ int rtpstream_packet(void *arg, packet_info *pinfo, epan_dissect_t *edt _U_, con
|
|||
}
|
||||
|
||||
/* get RTP stats for the packet */
|
||||
rtp_packet_analyse(&(stream_info->rtp_stats), pinfo, rtpinfo);
|
||||
rtppacket_analyse(&(stream_info->rtp_stats), pinfo, rtpinfo);
|
||||
if (stream_info->rtp_stats.flags & STAT_FLAG_WRONG_TIMESTAMP
|
||||
|| stream_info->rtp_stats.flags & STAT_FLAG_WRONG_SEQ)
|
||||
stream_info->problem = TRUE;
|
||||
|
@ -262,7 +262,7 @@ int rtpstream_packet(void *arg, packet_info *pinfo, epan_dissect_t *edt _U_, con
|
|||
return 1; /* refresh output */
|
||||
}
|
||||
else if (tapinfo->mode == TAP_SAVE) {
|
||||
if (rtp_stream_info_cmp(&new_stream_info, tapinfo->filter_stream_fwd)==0) {
|
||||
if (rtpstream_info_cmp(&new_stream_info, tapinfo->filter_stream_fwd)==0) {
|
||||
/* XXX - what if rtpinfo->info_all_data_present is
|
||||
FALSE, so that we don't *have* all the data? */
|
||||
rtpdump_info.rec_time = nstime_to_msec(&pinfo->abs_ts) -
|
||||
|
@ -273,8 +273,8 @@ int rtpstream_packet(void *arg, packet_info *pinfo, epan_dissect_t *edt _U_, con
|
|||
}
|
||||
}
|
||||
else if (tapinfo->mode == TAP_MARK && tapinfo->tap_mark_packet) {
|
||||
if (rtp_stream_info_cmp(&new_stream_info, tapinfo->filter_stream_fwd)==0
|
||||
|| rtp_stream_info_cmp(&new_stream_info, tapinfo->filter_stream_rev)==0)
|
||||
if (rtpstream_info_cmp(&new_stream_info, tapinfo->filter_stream_fwd)==0
|
||||
|| rtpstream_info_cmp(&new_stream_info, tapinfo->filter_stream_rev)==0)
|
||||
{
|
||||
tapinfo->tap_mark_packet(tapinfo, pinfo->fd);
|
||||
}
|
||||
|
@ -282,440 +282,6 @@ int rtpstream_packet(void *arg, packet_info *pinfo, epan_dissect_t *edt _U_, con
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
typedef struct _key_value {
|
||||
guint32 key;
|
||||
guint32 value;
|
||||
} key_value;
|
||||
|
||||
|
||||
/* RTP sampling clock rates for fixed payload types as defined in
|
||||
http://www.iana.org/assignments/rtp-parameters */
|
||||
static const key_value clock_map[] = {
|
||||
{PT_PCMU, 8000},
|
||||
{PT_1016, 8000},
|
||||
{PT_G721, 8000},
|
||||
{PT_GSM, 8000},
|
||||
{PT_G723, 8000},
|
||||
{PT_DVI4_8000, 8000},
|
||||
{PT_DVI4_16000, 16000},
|
||||
{PT_LPC, 8000},
|
||||
{PT_PCMA, 8000},
|
||||
{PT_G722, 8000},
|
||||
{PT_L16_STEREO, 44100},
|
||||
{PT_L16_MONO, 44100},
|
||||
{PT_QCELP, 8000},
|
||||
{PT_CN, 8000},
|
||||
{PT_MPA, 90000},
|
||||
{PT_G728, 8000},
|
||||
{PT_G728, 8000},
|
||||
{PT_DVI4_11025, 11025},
|
||||
{PT_DVI4_22050, 22050},
|
||||
{PT_G729, 8000},
|
||||
{PT_CN_OLD, 8000},
|
||||
{PT_CELB, 90000},
|
||||
{PT_JPEG, 90000},
|
||||
{PT_NV, 90000},
|
||||
{PT_H261, 90000},
|
||||
{PT_MPV, 90000},
|
||||
{PT_MP2T, 90000},
|
||||
{PT_H263, 90000},
|
||||
};
|
||||
|
||||
#define NUM_CLOCK_VALUES (sizeof clock_map / sizeof clock_map[0])
|
||||
|
||||
static guint32
|
||||
get_clock_rate(guint32 key)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < NUM_CLOCK_VALUES; i++) {
|
||||
if (clock_map[i].key == key)
|
||||
return clock_map[i].value;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
typedef struct _mimetype_and_clock {
|
||||
const gchar *pt_mime_name_str;
|
||||
guint32 value;
|
||||
} mimetype_and_clock;
|
||||
/* RTP sampling clock rates for
|
||||
"In addition to the RTP payload formats (encodings) listed in the RTP
|
||||
Payload Types table, there are additional payload formats that do not
|
||||
have static RTP payload types assigned but instead use dynamic payload
|
||||
type number assignment. Each payload format is named by a registered
|
||||
MIME subtype"
|
||||
http://www.iana.org/assignments/rtp-parameters.
|
||||
|
||||
NOTE: Please keep the mimetypes in case insensitive alphabetical order.
|
||||
*/
|
||||
static const mimetype_and_clock mimetype_and_clock_map[] = {
|
||||
{"AMR", 8000}, /* [RFC4867][RFC3267] */
|
||||
{"AMR-WB", 16000}, /* [RFC4867][RFC3267] */
|
||||
{"BMPEG", 90000}, /* [RFC2343],[RFC3555] */
|
||||
{"BT656", 90000}, /* [RFC2431],[RFC3555] */
|
||||
{"DV", 90000}, /* [RFC3189] */
|
||||
{"EVRC", 8000}, /* [RFC3558] */
|
||||
{"EVRC0", 8000}, /* [RFC4788] */
|
||||
{"EVRC1", 8000}, /* [RFC4788] */
|
||||
{"EVRCB", 8000}, /* [RFC4788] */
|
||||
{"EVRCB0", 8000}, /* [RFC4788] */
|
||||
{"EVRCB1", 8000}, /* [RFC4788] */
|
||||
{"EVRCWB", 16000}, /* [RFC5188] */
|
||||
{"EVRCWB0", 16000}, /* [RFC5188] */
|
||||
{"EVRCWB1", 16000}, /* [RFC5188] */
|
||||
{"EVS", 16000}, /* [3GPP TS 26.445] */
|
||||
{"G7221", 16000}, /* [RFC3047] */
|
||||
{"G726-16", 8000}, /* [RFC3551][RFC4856] */
|
||||
{"G726-24", 8000}, /* [RFC3551][RFC4856] */
|
||||
{"G726-32", 8000}, /* [RFC3551][RFC4856] */
|
||||
{"G726-40", 8000}, /* [RFC3551][RFC4856] */
|
||||
{"G729D", 8000}, /* [RFC3551][RFC4856] */
|
||||
{"G729E", 8000}, /* [RFC3551][RFC4856] */
|
||||
{"GSM-EFR", 8000}, /* [RFC3551] */
|
||||
{"H263-1998", 90000}, /* [RFC2429],[RFC3555] */
|
||||
{"H263-2000", 90000}, /* [RFC2429],[RFC3555] */
|
||||
{"H264", 90000}, /* [RFC3984] */
|
||||
{"MP1S", 90000}, /* [RFC2250],[RFC3555] */
|
||||
{"MP2P", 90000}, /* [RFC2250],[RFC3555] */
|
||||
{"MP4V-ES", 90000}, /* [RFC3016] */
|
||||
{"mpa-robust", 90000}, /* [RFC3119] */
|
||||
{"pointer", 90000}, /* [RFC2862] */
|
||||
{"raw", 90000}, /* [RFC4175] */
|
||||
{"red", 1000}, /* [RFC4102] */
|
||||
{"SMV", 8000}, /* [RFC3558] */
|
||||
{"SMV0", 8000}, /* [RFC3558] */
|
||||
{"t140", 1000}, /* [RFC4103] */
|
||||
{"telephone-event", 8000}, /* [RFC4733] */
|
||||
};
|
||||
|
||||
#define NUM_DYN_CLOCK_VALUES (sizeof mimetype_and_clock_map / sizeof mimetype_and_clock_map[0])
|
||||
|
||||
static guint32
|
||||
get_dyn_pt_clock_rate(const gchar *payload_type_str)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Search for matching mimetype in reverse order to avoid false matches
|
||||
* when pt_mime_name_str is the prefix of payload_type_str */
|
||||
for (i = NUM_DYN_CLOCK_VALUES - 1; i > -1 ; i--) {
|
||||
if (g_ascii_strncasecmp(mimetype_and_clock_map[i].pt_mime_name_str,payload_type_str,(strlen(mimetype_and_clock_map[i].pt_mime_name_str))) == 0)
|
||||
return mimetype_and_clock_map[i].value;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
void
|
||||
rtp_packet_analyse(tap_rtp_stat_t *statinfo,
|
||||
packet_info *pinfo,
|
||||
const struct _rtp_info *rtpinfo)
|
||||
{
|
||||
double current_time;
|
||||
double current_jitter;
|
||||
double current_diff = 0;
|
||||
double nominaltime;
|
||||
double arrivaltime; /* Time relative to start_time */
|
||||
double expected_time;
|
||||
double absskew;
|
||||
guint32 clock_rate;
|
||||
|
||||
/* Store the current time */
|
||||
current_time = nstime_to_msec(&pinfo->rel_ts);
|
||||
|
||||
/* Is this the first packet we got in this direction? */
|
||||
if (statinfo->first_packet) {
|
||||
/* Save the MAC address of the first RTP frame */
|
||||
if( pinfo->dl_src.type == AT_ETHER){
|
||||
copy_address(&(statinfo->first_packet_mac_addr), &(pinfo->dl_src));
|
||||
}
|
||||
statinfo->start_seq_nr = rtpinfo->info_seq_num;
|
||||
statinfo->stop_seq_nr = rtpinfo->info_seq_num;
|
||||
statinfo->seq_num = rtpinfo->info_seq_num;
|
||||
statinfo->start_time = current_time;
|
||||
statinfo->timestamp = rtpinfo->info_timestamp;
|
||||
statinfo->first_timestamp = rtpinfo->info_timestamp;
|
||||
statinfo->time = current_time;
|
||||
statinfo->lastnominaltime = 0;
|
||||
statinfo->pt = rtpinfo->info_payload_type;
|
||||
statinfo->reg_pt = rtpinfo->info_payload_type;
|
||||
if (pinfo->net_src.type == AT_IPv6) {
|
||||
statinfo->bw_history[statinfo->bw_index].bytes = rtpinfo->info_data_len + 48;
|
||||
} else {
|
||||
statinfo->bw_history[statinfo->bw_index].bytes = rtpinfo->info_data_len + 28;
|
||||
}
|
||||
statinfo->bw_history[statinfo->bw_index].time = current_time;
|
||||
statinfo->bw_index++;
|
||||
if (pinfo->net_src.type == AT_IPv6) {
|
||||
statinfo->total_bytes += rtpinfo->info_data_len + 48;
|
||||
} else {
|
||||
statinfo->total_bytes += rtpinfo->info_data_len + 28;
|
||||
}
|
||||
statinfo->bandwidth = (double)(statinfo->total_bytes*8)/1000;
|
||||
/* Not needed ? initialised to zero? */
|
||||
statinfo->delta = 0;
|
||||
statinfo->jitter = 0;
|
||||
statinfo->diff = 0;
|
||||
|
||||
statinfo->total_nr++;
|
||||
statinfo->flags |= STAT_FLAG_FIRST;
|
||||
if (rtpinfo->info_marker_set) {
|
||||
statinfo->flags |= STAT_FLAG_MARKER;
|
||||
}
|
||||
statinfo->first_packet_num = pinfo->num;
|
||||
statinfo->first_packet = FALSE;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Reset flags */
|
||||
statinfo->flags = 0;
|
||||
#if 0
|
||||
/*According to bug https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=11478
|
||||
* this code causes problems. A better solution is needed if there is need for the functionality */
|
||||
/* Try to detect duplicated packets due to mirroring/span ports by comparing src MAC addresses.
|
||||
* Chek for duplicates (src mac differs from first_packet_mac_addr) */
|
||||
*/
|
||||
if( pinfo->dl_src.type == AT_ETHER){
|
||||
if(!addresses_equal(&(statinfo->first_packet_mac_addr), &(pinfo->dl_src))){
|
||||
statinfo->flags |= STAT_FLAG_DUP_PKT;
|
||||
statinfo->delta = current_time-(statinfo->time);
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/* When calculating expected rtp packets the seq number can wrap around
|
||||
* so we have to count the number of cycles
|
||||
* Variable cycles counts the wraps around in forwarding connection and
|
||||
* under is flag that indicates where we are
|
||||
*
|
||||
* XXX How to determine number of cycles with all possible lost, late
|
||||
* and duplicated packets without any doubt? It seems to me, that
|
||||
* because of all possible combination of late, duplicated or lost
|
||||
* packets, this can only be more or less good approximation
|
||||
*
|
||||
* There are some combinations (rare but theoretically possible),
|
||||
* where below code won't work correctly - statistic may be wrong then.
|
||||
*/
|
||||
|
||||
/* So if the current sequence number is less than the start one
|
||||
* we assume, that there is another cycle running
|
||||
*/
|
||||
if ((rtpinfo->info_seq_num < statinfo->start_seq_nr) && (statinfo->under == FALSE)){
|
||||
statinfo->cycles++;
|
||||
statinfo->under = TRUE;
|
||||
}
|
||||
/* what if the start seq nr was 0? Then the above condition will never
|
||||
* be true, so we add another condition. XXX The problem would arise
|
||||
* if one of the packets with seq nr 0 or 65535 would be lost or late
|
||||
*/
|
||||
else if ((rtpinfo->info_seq_num == 0) && (statinfo->stop_seq_nr == 65535) &&
|
||||
(statinfo->under == FALSE)) {
|
||||
statinfo->cycles++;
|
||||
statinfo->under = TRUE;
|
||||
}
|
||||
/* the whole round is over, so reset the flag */
|
||||
else if ((rtpinfo->info_seq_num > statinfo->start_seq_nr) && (statinfo->under != FALSE)) {
|
||||
statinfo->under = FALSE;
|
||||
}
|
||||
|
||||
/* Since it is difficult to count lost, duplicate or late packets separately,
|
||||
* we would like to know at least how many times the sequence number was not ok
|
||||
*/
|
||||
|
||||
/* If the current seq number equals the last one or if we are here for
|
||||
* the first time, then it is ok, we just store the current one as the last one
|
||||
*/
|
||||
if ( (statinfo->seq_num+1 == rtpinfo->info_seq_num) || (statinfo->flags & STAT_FLAG_FIRST) )
|
||||
statinfo->seq_num = rtpinfo->info_seq_num;
|
||||
/* If the first one is 65535 we wrap */
|
||||
else if ( (statinfo->seq_num == 65535) && (rtpinfo->info_seq_num == 0) )
|
||||
statinfo->seq_num = rtpinfo->info_seq_num;
|
||||
/* Lost packets. If the prev seq is enormously larger than the cur seq
|
||||
* we assume that instead of being massively late we lost the packet(s)
|
||||
* that would have indicated the sequence number wrapping. An imprecise
|
||||
* heuristic at best, but it seems to work well enough.
|
||||
* https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=5958 */
|
||||
else if (statinfo->seq_num+1 < rtpinfo->info_seq_num || statinfo->seq_num - rtpinfo->info_seq_num > 0xFF00) {
|
||||
statinfo->seq_num = rtpinfo->info_seq_num;
|
||||
statinfo->sequence++;
|
||||
statinfo->flags |= STAT_FLAG_WRONG_SEQ;
|
||||
}
|
||||
/* Late or duplicated */
|
||||
else if (statinfo->seq_num+1 > rtpinfo->info_seq_num) {
|
||||
statinfo->sequence++;
|
||||
statinfo->flags |= STAT_FLAG_WRONG_SEQ;
|
||||
}
|
||||
|
||||
/* Check payload type */
|
||||
if (rtpinfo->info_payload_type == PT_CN
|
||||
|| rtpinfo->info_payload_type == PT_CN_OLD)
|
||||
statinfo->flags |= STAT_FLAG_PT_CN;
|
||||
if (statinfo->pt == PT_CN
|
||||
|| statinfo->pt == PT_CN_OLD)
|
||||
statinfo->flags |= STAT_FLAG_FOLLOW_PT_CN;
|
||||
if (rtpinfo->info_payload_type != statinfo->pt)
|
||||
statinfo->flags |= STAT_FLAG_PT_CHANGE;
|
||||
statinfo->pt = rtpinfo->info_payload_type;
|
||||
|
||||
/*
|
||||
* Return for unknown payload types
|
||||
* Ignore jitter calculation for clockrate = 0
|
||||
*/
|
||||
if (statinfo->pt < 96 ){
|
||||
clock_rate = get_clock_rate(statinfo->pt);
|
||||
} else { /* Dynamic PT */
|
||||
if ( rtpinfo->info_payload_type_str != NULL ) {
|
||||
/* Is it a "telephone-event" ?
|
||||
* Timestamp is not increased for telepone-event packets impacting
|
||||
* calculation of Jitter Skew and clock drift.
|
||||
* see 2.2.1 of RFC 4733
|
||||
*/
|
||||
if (g_ascii_strncasecmp("telephone-event",rtpinfo->info_payload_type_str,(strlen("telephone-event")))==0) {
|
||||
clock_rate = 0;
|
||||
statinfo->flags |= STAT_FLAG_PT_T_EVENT;
|
||||
} else {
|
||||
if(rtpinfo->info_payload_rate !=0) {
|
||||
clock_rate = rtpinfo->info_payload_rate;
|
||||
} else {
|
||||
clock_rate = get_dyn_pt_clock_rate(rtpinfo->info_payload_type_str);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
clock_rate = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Handle wraparound ? */
|
||||
arrivaltime = current_time - statinfo->start_time;
|
||||
|
||||
nominaltime = (double)(guint32_wraparound_diff(rtpinfo->info_timestamp, statinfo->first_timestamp));
|
||||
|
||||
/* Can only analyze defined sampling rates */
|
||||
if (clock_rate != 0) {
|
||||
statinfo->clock_rate = clock_rate;
|
||||
/* Convert from sampling clock to ms */
|
||||
nominaltime = nominaltime /(clock_rate/1000);
|
||||
|
||||
/* Calculate the current jitter(in ms) */
|
||||
if (!statinfo->first_packet) {
|
||||
expected_time = statinfo->time + (nominaltime - statinfo->lastnominaltime);
|
||||
current_diff = fabs(current_time - expected_time);
|
||||
current_jitter = (15 * statinfo->jitter + current_diff) / 16;
|
||||
|
||||
statinfo->delta = current_time-(statinfo->time);
|
||||
statinfo->jitter = current_jitter;
|
||||
statinfo->diff = current_diff;
|
||||
}
|
||||
statinfo->lastnominaltime = nominaltime;
|
||||
/* Calculate skew, i.e. absolute jitter that also catches clock drift
|
||||
* Skew is positive if TS (nominal) is too fast
|
||||
*/
|
||||
statinfo->skew = nominaltime - arrivaltime;
|
||||
absskew = fabs(statinfo->skew);
|
||||
if(absskew > fabs(statinfo->max_skew)) {
|
||||
statinfo->max_skew = statinfo->skew;
|
||||
}
|
||||
/* Gather data for calculation of average, minimum and maximum framerate based on timestamp */
|
||||
#if 0
|
||||
if (numPackets > 0 && (!hardPayloadType || !alternatePayloadType)) {
|
||||
/* Skip first packet and possibly alternate payload type packets */
|
||||
double dt;
|
||||
dt = nominaltime - statinfo->lastnominaltime;
|
||||
sumdt += 1.0 * dt;
|
||||
numdt += (dt != 0 ? 1 : 0);
|
||||
mindt = (dt < mindt ? dt : mindt);
|
||||
maxdt = (dt > maxdt ? dt : maxdt);
|
||||
}
|
||||
#endif
|
||||
/* Gather data for calculation of skew least square */
|
||||
statinfo->sumt += 1.0 * current_time;
|
||||
statinfo->sumTS += 1.0 * nominaltime;
|
||||
statinfo->sumt2 += 1.0 * current_time * current_time;
|
||||
statinfo->sumtTS += 1.0 * current_time * nominaltime;
|
||||
}
|
||||
|
||||
/* Calculate the BW in Kbps adding the IP+UDP header to the RTP -> 20bytes(IP) + 8bytes(UDP) */
|
||||
if (pinfo->net_src.type == AT_IPv6) {
|
||||
statinfo->bw_history[statinfo->bw_index].bytes = rtpinfo->info_data_len + 48;
|
||||
} else {
|
||||
statinfo->bw_history[statinfo->bw_index].bytes = rtpinfo->info_data_len + 28;
|
||||
}
|
||||
statinfo->bw_history[statinfo->bw_index].time = current_time;
|
||||
|
||||
/* Check if there are more than 1sec in the history buffer to calculate BW in bps. If so, remove those for the calculation */
|
||||
while ((statinfo->bw_history[statinfo->bw_start_index].time+1000/* ms */)<current_time){
|
||||
statinfo->total_bytes -= statinfo->bw_history[statinfo->bw_start_index].bytes;
|
||||
statinfo->bw_start_index++;
|
||||
if (statinfo->bw_start_index == BUFF_BW) statinfo->bw_start_index=0;
|
||||
};
|
||||
/* IP hdr + UDP + RTP */
|
||||
if (pinfo->net_src.type == AT_IPv6){
|
||||
statinfo->total_bytes += rtpinfo->info_data_len + 48;
|
||||
}else{
|
||||
statinfo->total_bytes += rtpinfo->info_data_len + 28;
|
||||
}
|
||||
statinfo->bandwidth = (double)(statinfo->total_bytes*8)/1000;
|
||||
statinfo->bw_index++;
|
||||
if (statinfo->bw_index == BUFF_BW) statinfo->bw_index = 0;
|
||||
|
||||
|
||||
/* Used by GTK code only */
|
||||
statinfo->delta_timestamp = guint32_wraparound_diff(rtpinfo->info_timestamp, statinfo->timestamp);
|
||||
|
||||
/* Is it a packet with the mark bit set? */
|
||||
if (rtpinfo->info_marker_set) {
|
||||
statinfo->flags |= STAT_FLAG_MARKER;
|
||||
}
|
||||
|
||||
/* Difference can be negative. We don't expect difference bigger than 31 bits. Difference don't care about wrap around. */
|
||||
gint32 tsdelta=rtpinfo->info_timestamp - statinfo->timestamp;
|
||||
if (tsdelta < 0) {
|
||||
statinfo->flags |= STAT_FLAG_WRONG_TIMESTAMP;
|
||||
}
|
||||
/* Is it a regular packet? */
|
||||
if (!(statinfo->flags & STAT_FLAG_FIRST)
|
||||
&& !(statinfo->flags & STAT_FLAG_MARKER)
|
||||
&& !(statinfo->flags & STAT_FLAG_PT_CN)
|
||||
&& !(statinfo->flags & STAT_FLAG_WRONG_TIMESTAMP)
|
||||
&& !(statinfo->flags & STAT_FLAG_FOLLOW_PT_CN)) {
|
||||
/* Include it in maximum delta calculation */
|
||||
if (statinfo->delta > statinfo->max_delta) {
|
||||
statinfo->max_delta = statinfo->delta;
|
||||
statinfo->max_nr = pinfo->num;
|
||||
}
|
||||
if (clock_rate != 0) {
|
||||
/* Maximum and mean jitter calculation */
|
||||
if (statinfo->jitter > statinfo->max_jitter) {
|
||||
statinfo->max_jitter = statinfo->jitter;
|
||||
}
|
||||
statinfo->mean_jitter = (statinfo->mean_jitter*statinfo->total_nr + current_diff) / (statinfo->total_nr+1);
|
||||
}
|
||||
}
|
||||
/* Regular payload change? (CN ignored) */
|
||||
if (!(statinfo->flags & STAT_FLAG_FIRST)
|
||||
&& !(statinfo->flags & STAT_FLAG_PT_CN)) {
|
||||
if ((statinfo->pt != statinfo->reg_pt)
|
||||
&& (statinfo->reg_pt != PT_UNDEFINED)) {
|
||||
statinfo->flags |= STAT_FLAG_REG_PT_CHANGE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set regular payload*/
|
||||
if (!(statinfo->flags & STAT_FLAG_PT_CN)) {
|
||||
statinfo->reg_pt = statinfo->pt;
|
||||
}
|
||||
|
||||
statinfo->time = current_time;
|
||||
statinfo->timestamp = rtpinfo->info_timestamp;
|
||||
statinfo->stop_seq_nr = rtpinfo->info_seq_num;
|
||||
statinfo->total_nr++;
|
||||
statinfo->last_payload_len = rtpinfo->info_payload_len - rtpinfo->info_padding_count;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Editor modelines - https://www.wireshark.org/tools/modelines.html
|
||||
*
|
||||
|
|
|
@ -22,29 +22,30 @@
|
|||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#include "ui/rtp_stream.h"
|
||||
|
||||
/* type of error when saving voice in a file didn't succeed */
|
||||
typedef enum {
|
||||
TAP_RTP_NO_ERROR,
|
||||
TAP_RTP_WRONG_CODEC,
|
||||
TAP_RTP_WRONG_LENGTH,
|
||||
TAP_RTP_PADDING_ERROR,
|
||||
TAP_RTP_SHORT_FRAME,
|
||||
TAP_RTP_FILE_OPEN_ERROR,
|
||||
TAP_RTP_FILE_WRITE_ERROR,
|
||||
TAP_RTP_NO_DATA
|
||||
} error_type_t;
|
||||
TAP_RTP_NO_DATA,
|
||||
} tap_rtp_error_type_t;
|
||||
|
||||
typedef struct _tap_rtp_save_info_t {
|
||||
FILE *fp;
|
||||
guint32 count;
|
||||
error_type_t error_type;
|
||||
tap_rtp_error_type_t error_type;
|
||||
gboolean saved;
|
||||
} tap_rtp_save_info_t;
|
||||
|
||||
struct _rtp_stream_info;
|
||||
|
||||
void rtpstream_reset_cb(void*);
|
||||
void rtp_write_header(struct _rtp_stream_info*, FILE*);
|
||||
int rtpstream_packet(void*, packet_info*, epan_dissect_t *, const void *);
|
||||
void rtp_write_header(rtpstream_info_t*, FILE*);
|
||||
int rtpstream_packet_cb(void*, packet_info*, epan_dissect_t *, const void *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -259,7 +259,7 @@ void
|
|||
voip_calls_reset_all_taps(voip_calls_tapinfo_t *tapinfo)
|
||||
{
|
||||
voip_calls_info_t *callsinfo;
|
||||
rtp_stream_info_t *strinfo;
|
||||
rtpstream_info_t *strinfo;
|
||||
GList *list = NULL;
|
||||
|
||||
/* VOIP_CALLS_DEBUG("reset packets: %d streams: %d", tapinfo->npackets, tapinfo->nrtp_streams); */
|
||||
|
@ -291,7 +291,7 @@ voip_calls_reset_all_taps(voip_calls_tapinfo_t *tapinfo)
|
|||
list = g_list_first(tapinfo->rtp_stream_list);
|
||||
while(list)
|
||||
{
|
||||
strinfo = (rtp_stream_info_t *)list->data;
|
||||
strinfo = (rtpstream_info_t *)list->data;
|
||||
wmem_free(NULL, strinfo->payload_type_name);
|
||||
wmem_free(NULL, strinfo->ed137_info);
|
||||
list = g_list_next(list);
|
||||
|
@ -580,8 +580,8 @@ static gboolean
|
|||
rtp_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, void const *rtp_info_ptr)
|
||||
{
|
||||
voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_rtp_);
|
||||
rtp_stream_info_t *tmp_listinfo;
|
||||
rtp_stream_info_t *strinfo = NULL;
|
||||
rtpstream_info_t *tmp_listinfo;
|
||||
rtpstream_info_t *strinfo = NULL;
|
||||
GList *list;
|
||||
struct _rtp_conversation_info *p_conv_data = NULL;
|
||||
|
||||
|
@ -600,7 +600,7 @@ rtp_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, void c
|
|||
list = g_list_first(tapinfo->rtp_stream_list);
|
||||
while (list)
|
||||
{
|
||||
tmp_listinfo=(rtp_stream_info_t *)list->data;
|
||||
tmp_listinfo=(rtpstream_info_t *)list->data;
|
||||
if ( (tmp_listinfo->setup_frame_number == rtp_info->info_setup_frame_num)
|
||||
&& (tmp_listinfo->ssrc == rtp_info->info_sync_src) && (tmp_listinfo->end_stream == FALSE)) {
|
||||
/* if the payload type has changed, we mark the stream as finished to create a new one
|
||||
|
@ -616,7 +616,7 @@ rtp_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, void c
|
|||
/* if ed137_info has changed, create new stream */
|
||||
tmp_listinfo->end_stream = TRUE;
|
||||
} else {
|
||||
strinfo = (rtp_stream_info_t*)(list->data);
|
||||
strinfo = (rtpstream_info_t*)(list->data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -630,7 +630,7 @@ rtp_packet(void *tap_offset_ptr, packet_info *pinfo, epan_dissect_t *edt, void c
|
|||
|
||||
/* not in the list? then create a new entry */
|
||||
if (strinfo==NULL) {
|
||||
strinfo = (rtp_stream_info_t *)g_malloc0(sizeof(rtp_stream_info_t));
|
||||
strinfo = (rtpstream_info_t *)g_malloc0(sizeof(rtpstream_info_t));
|
||||
copy_address(&(strinfo->src_addr), &(pinfo->src));
|
||||
strinfo->src_port = pinfo->srcport;
|
||||
copy_address(&(strinfo->dest_addr), &(pinfo->dst));
|
||||
|
@ -688,7 +688,7 @@ rtp_draw(void *tap_offset_ptr)
|
|||
{
|
||||
voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_rtp_);
|
||||
GList *rtp_streams_list;
|
||||
rtp_stream_info_t *rtp_listinfo;
|
||||
rtpstream_info_t *rtp_listinfo;
|
||||
/* GList *voip_calls_graph_list; */
|
||||
seq_analysis_item_t *gai = NULL;
|
||||
seq_analysis_item_t *new_gai;
|
||||
|
@ -700,7 +700,7 @@ rtp_draw(void *tap_offset_ptr)
|
|||
rtp_streams_list = g_list_first(tapinfo->rtp_stream_list);
|
||||
while (rtp_streams_list)
|
||||
{
|
||||
rtp_listinfo = (rtp_stream_info_t *)rtp_streams_list->data;
|
||||
rtp_listinfo = (rtpstream_info_t *)rtp_streams_list->data;
|
||||
|
||||
/* using the setup frame number of the RTP stream, we get the call number that it belongs to*/
|
||||
/* voip_calls_graph_list = g_list_first(tapinfo->graph_analysis->list); */
|
||||
|
@ -761,7 +761,7 @@ rtp_packet_draw(void *tap_offset_ptr)
|
|||
{
|
||||
voip_calls_tapinfo_t *tapinfo = tap_id_to_base(tap_offset_ptr, tap_id_offset_rtp_);
|
||||
GList *rtp_streams_list;
|
||||
rtp_stream_info_t *rtp_listinfo;
|
||||
rtpstream_info_t *rtp_listinfo;
|
||||
GList *voip_calls_graph_list;
|
||||
guint item;
|
||||
seq_analysis_item_t *gai;
|
||||
|
|
Loading…
Reference in New Issue