summaryrefslogtreecommitdiff
path: root/epan
diff options
context:
space:
mode:
authorMichal Labedzki <michal.labedzki@tieto.com>2014-03-27 07:59:16 +0100
committerMichal Labedzki <michal.labedzki@tieto.com>2014-05-30 11:24:19 +0000
commit32e66a4cc663e5ec351872f6d4445d2b8c53a071 (patch)
treec986d23c29c5bfd5367892bdda33b2160a7673e9 /epan
parent788228428eab63a794f029e4ba6ee3b641943a36 (diff)
downloadwireshark-32e66a4cc663e5ec351872f6d4445d2b8c53a071.tar.gz
Bluetooth: Add music duration info for SBC
Music duration info can be used to detect underflow, what can decrease music quality. Change-Id: I8ea06655395d3e66473a09ee72b6833b894aa6e1 Reviewed-on: https://code.wireshark.org/review/1052 Reviewed-by: Michal Labedzki <michal.labedzki@tieto.com>
Diffstat (limited to 'epan')
-rw-r--r--epan/dissectors/packet-btavdtp.c103
-rw-r--r--epan/dissectors/packet-btavdtp.h12
-rw-r--r--epan/dissectors/packet-rtp.c2
-rw-r--r--epan/dissectors/packet-sbc.c95
4 files changed, 189 insertions, 23 deletions
diff --git a/epan/dissectors/packet-btavdtp.c b/epan/dissectors/packet-btavdtp.c
index 58a9719134..a717091329 100644
--- a/epan/dissectors/packet-btavdtp.c
+++ b/epan/dissectors/packet-btavdtp.c
@@ -246,9 +246,11 @@ static dissector_handle_t bta2dp_handle;
static dissector_handle_t btvdp_handle;
static dissector_handle_t rtp_handle;
-static wmem_tree_t *sep_list = NULL;
-static wmem_tree_t *sep_open = NULL;
-static wmem_tree_t *cid_to_type_table = NULL;
+
+static wmem_tree_t *sep_list = NULL;
+static wmem_tree_t *sep_open = NULL;
+static wmem_tree_t *cid_to_type_table = NULL;
+static wmem_tree_t *media_packet_times = NULL;
/* A2DP declarations */
static gint proto_bta2dp = -1;
@@ -468,12 +470,13 @@ typedef struct _cid_type_data_t {
sep_entry_t *sep;
} cid_type_data_t;
-
typedef struct _sep_data_t {
- gint codec;
- guint8 acp_seid;
- guint8 int_seid;
- gint content_protection_type;
+ gint codec;
+ guint8 acp_seid;
+ guint8 int_seid;
+ gint content_protection_type;
+ media_packet_info_t *previous_media_packet_info;
+ media_packet_info_t *current_media_packet_info;
} sep_data_t;
void proto_register_btavdtp(void);
@@ -1140,11 +1143,13 @@ dissect_btavdtp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
key[3].length = 1;
key[3].key = &cid;
key[4].length = 1;
- key[4].key = &type;
+ key[4].key = &direction;
key[5].length = 1;
- key[5].key = &frame_number;
- key[6].length = 0;
- key[6].key = NULL;
+ key[5].key = &type;
+ key[6].length = 1;
+ key[6].key = &frame_number;
+ key[7].length = 0;
+ key[7].key = NULL;
wmem_tree_insert32_array(cid_to_type_table, key, cid_type_data);
}
@@ -1164,8 +1169,10 @@ dissect_btavdtp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
key[2].key = &chandle;
key[3].length = 1;
key[3].key = &cid;
- key[4].length = 0;
- key[4].key = NULL;
+ key[4].length = 1;
+ key[4].key = &direction;
+ key[5].length = 0;
+ key[5].key = NULL;
subtree = (wmem_tree_t *) wmem_tree_lookup32_array(cid_to_type_table, key);
if (subtree) {
wmem_tree_t *type_tree;
@@ -1202,13 +1209,74 @@ dissect_btavdtp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
pinfo->fd->num));
if (cid_type_data->sep->media_type == MEDIA_TYPE_AUDIO) {
- sep_data_t sep_data;
+ sep_data_t sep_data;
+ media_packet_info_t *previous_media_packet_info;
+ media_packet_info_t *current_media_packet_info;
+ nstime_t first_abs_ts;
+ gdouble cummulative_frame_duration;
sep_data.codec = cid_type_data->sep->codec;
sep_data.acp_seid = cid_type_data->sep->seid;
sep_data.int_seid = cid_type_data->sep->int_seid;
sep_data.content_protection_type = cid_type_data->sep->content_protection_type;
+ interface_id = cid_type_data->interface_id;
+ adapter_id = cid_type_data->adapter_id;
+ chandle = cid_type_data->chandle;
+ cid = cid_type_data->cid;
+ frame_number = pinfo->fd->num;
+
+ key[0].length = 1;
+ key[0].key = &interface_id;
+ key[1].length = 1;
+ key[1].key = &adapter_id;
+ key[2].length = 1;
+ key[2].key = &chandle;
+ key[3].length = 1;
+ key[3].key = &cid;
+ key[4].length = 1;
+ key[4].key = &direction;
+ key[5].length = 0;
+ key[5].key = NULL;
+ subtree = (wmem_tree_t *) wmem_tree_lookup32_array(media_packet_times, key);
+
+ previous_media_packet_info = (subtree) ? (media_packet_info_t *) wmem_tree_lookup32_le(subtree, frame_number - 1) : NULL;
+ if (previous_media_packet_info) {
+ sep_data.previous_media_packet_info = previous_media_packet_info;
+ first_abs_ts = previous_media_packet_info->first_abs_ts;
+ cummulative_frame_duration = previous_media_packet_info->cummulative_frame_duration;
+ } else {
+ first_abs_ts = pinfo->fd->abs_ts;
+ cummulative_frame_duration = 0.0;
+ sep_data.previous_media_packet_info = (media_packet_info_t *) wmem_new(wmem_epan_scope(), media_packet_info_t);
+ sep_data.previous_media_packet_info->abs_ts = pinfo->fd->abs_ts;
+ sep_data.previous_media_packet_info->first_abs_ts = first_abs_ts;
+ sep_data.previous_media_packet_info->cummulative_frame_duration = cummulative_frame_duration;
+ }
+
+ if (!pinfo->fd->flags.visited) {
+ key[5].length = 1;
+ key[5].key = &frame_number;
+ key[6].length = 0;
+ key[6].key = NULL;
+
+ current_media_packet_info = wmem_new(wmem_file_scope(), media_packet_info_t);
+ current_media_packet_info->abs_ts = pinfo->fd->abs_ts;
+ current_media_packet_info->first_abs_ts = first_abs_ts;
+ current_media_packet_info->cummulative_frame_duration = cummulative_frame_duration;
+
+ wmem_tree_insert32_array(media_packet_times, key, current_media_packet_info);
+ }
+
+ key[5].length = 0;
+ key[5].key = NULL;
+ subtree = (wmem_tree_t *) wmem_tree_lookup32_array(media_packet_times, key);
+ current_media_packet_info = (subtree) ? (media_packet_info_t *) wmem_tree_lookup32(subtree, frame_number) : NULL;
+ if (current_media_packet_info)
+ sep_data.current_media_packet_info = current_media_packet_info;
+ else
+ sep_data.current_media_packet_info = NULL;
+
next_tvb = tvb_new_subset_remaining(tvb, offset);
call_dissector_with_data(bta2dp_handle, next_tvb, pinfo, tree, &sep_data);
} else if (cid_type_data->sep->media_type == MEDIA_TYPE_VIDEO) {
@@ -2225,6 +2293,7 @@ proto_register_btavdtp(void)
sep_list = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
sep_open = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
cid_to_type_table = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope()); /* cid: type */
+ media_packet_times = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope());
}
void
@@ -2253,6 +2322,8 @@ dissect_bta2dp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
sep_data.content_protection_type = 0;
sep_data.acp_seid = 0;
sep_data.int_seid = 0;
+ sep_data.previous_media_packet_info = NULL;
+ sep_data.current_media_packet_info = NULL;
if (force_a2dp_scms_t || force_a2dp_codec != CODEC_DEFAULT) {
if (force_a2dp_scms_t)
@@ -2328,6 +2399,8 @@ dissect_bta2dp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
bta2dp_codec_info.codec_dissector = codec_dissector;
bta2dp_codec_info.content_protection_type = sep_data.content_protection_type;
+ bta2dp_codec_info.previous_media_packet_info = sep_data.previous_media_packet_info;
+ bta2dp_codec_info.current_media_packet_info = sep_data.current_media_packet_info;
bluetooth_add_address(pinfo, &pinfo->net_dst, "BT A2DP", pinfo->fd->num, FALSE, &bta2dp_codec_info);
call_dissector(rtp_handle, tvb, pinfo, tree);
diff --git a/epan/dissectors/packet-btavdtp.h b/epan/dissectors/packet-btavdtp.h
index ac20e0d7e0..33f44c8165 100644
--- a/epan/dissectors/packet-btavdtp.h
+++ b/epan/dissectors/packet-btavdtp.h
@@ -27,9 +27,17 @@
#define BTAVDTP_CONTENT_PROTECTION_TYPE_SCMS_T 0x02
+typedef struct _media_packet_info_t {
+ nstime_t abs_ts;
+ nstime_t first_abs_ts;
+ gdouble cummulative_frame_duration;
+} media_packet_info_t;
+
typedef struct _bta2dp_codec_info_t {
- dissector_handle_t codec_dissector;
- gint content_protection_type;
+ dissector_handle_t codec_dissector;
+ gint content_protection_type;
+ media_packet_info_t *previous_media_packet_info;
+ media_packet_info_t *current_media_packet_info;
} bta2dp_codec_info_t;
typedef struct _btvdp_codec_info_t {
diff --git a/epan/dissectors/packet-rtp.c b/epan/dissectors/packet-rtp.c
index 72c41fd693..cf7fe6da5b 100644
--- a/epan/dissectors/packet-rtp.c
+++ b/epan/dissectors/packet-rtp.c
@@ -1470,7 +1470,7 @@ process_rtp_payload(tvbuff_t *newtvb, packet_info *pinfo, proto_tree *tree,
nexttvb = tvb_new_subset_remaining(newtvb, suboffset);
if (p_conv_data->bta2dp_info->codec_dissector)
- call_dissector(p_conv_data->bta2dp_info->codec_dissector, nexttvb, pinfo, tree);
+ call_dissector_with_data(p_conv_data->bta2dp_info->codec_dissector, nexttvb, pinfo, tree, p_conv_data->bta2dp_info);
else
call_dissector(data_handle, nexttvb, pinfo, tree);
} else if (p_conv_data && p_conv_data->btvdp_info) {
diff --git a/epan/dissectors/packet-sbc.c b/epan/dissectors/packet-sbc.c
index 95713d028c..e23765094f 100644
--- a/epan/dissectors/packet-sbc.c
+++ b/epan/dissectors/packet-sbc.c
@@ -28,6 +28,8 @@
#include <epan/expert.h>
#include <epan/prefs.h>
+#include "packet-btavdtp.h"
+
#define CHANNELS_MONO 0x00
#define CHANNELS_JOINT_STEREO 0x03
@@ -54,6 +56,13 @@ static int hf_sbc_allocation_method = -1;
static int hf_sbc_subbands = -1;
static int hf_sbc_bitpool = -1;
static int hf_sbc_crc_check = -1;
+static int hf_sbc_expected_data_speed = -1;
+static int hf_sbc_frame_duration = -1;
+static int hf_sbc_cummulative_frame_duration = -1;
+static int hf_sbc_delta_time = -1;
+static int hf_sbc_delta_time_from_the_beginning = -1;
+static int hf_sbc_cummulative_duration = -1;
+static int hf_sbc_diff = -1;
static int hf_sbc_data = -1;
@@ -102,7 +111,7 @@ static const value_string subbands_vals[] = {
static gint
-dissect_sbc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
+dissect_sbc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
{
proto_item *ti;
proto_tree *sbc_tree;
@@ -125,9 +134,14 @@ dissect_sbc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
gint counter = 1;
gint frame_length;
gint expected_speed_data;
+ gdouble frame_duration;
+ gdouble cummulative_frame_duration = 0;
+ bta2dp_codec_info_t *info;
col_set_str(pinfo->cinfo, COL_PROTOCOL, "SBC");
+ info = (bta2dp_codec_info_t *) data;
+
ti = proto_tree_add_item(tree, proto_sbc, tvb, offset, -1, ENC_NA);
sbc_tree = proto_item_add_subtree(ti, ett_sbc);
@@ -212,14 +226,51 @@ dissect_sbc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
proto_tree_add_item(ritem, hf_sbc_data, tvb, offset, frame_length, ENC_NA);
offset += frame_length;
-/* TODO: expert_info for invalid CRC*/
+/* TODO: expert_info for invalid CRC */
+
+ pitem = proto_tree_add_uint(ritem, hf_sbc_expected_data_speed, tvb, offset, 0, expected_speed_data / 1024);
+ proto_item_append_text(pitem, " KiB/s");
+ PROTO_ITEM_SET_GENERATED(pitem);
+
+ frame_duration = (((double) frame_length / (double) expected_speed_data) * 1000.0);
+ cummulative_frame_duration += frame_duration;
- pitem = proto_tree_add_text(ritem, tvb, offset, 0, "Expected speed data: %u KiB/s", expected_speed_data / 1024);
+ pitem = proto_tree_add_double(ritem, hf_sbc_frame_duration, tvb, offset, 0, frame_duration);
+ proto_item_append_text(pitem, " ms");
PROTO_ITEM_SET_GENERATED(pitem);
counter += 1;
}
+ pitem = proto_tree_add_double(sbc_tree, hf_sbc_cummulative_frame_duration, tvb, offset, 0, cummulative_frame_duration);
+ proto_item_append_text(pitem, " ms");
+ PROTO_ITEM_SET_GENERATED(pitem);
+
+ if (info && info->previous_media_packet_info && info->current_media_packet_info) {
+ nstime_t delta;
+
+ nstime_delta(&delta, &pinfo->fd->abs_ts, &info->previous_media_packet_info->abs_ts);
+ pitem = proto_tree_add_double(sbc_tree, hf_sbc_delta_time, tvb, offset, 0, nstime_to_msec(&delta));
+ proto_item_append_text(pitem, " ms");
+ PROTO_ITEM_SET_GENERATED(pitem);
+
+ nstime_delta(&delta, &pinfo->fd->abs_ts, &info->previous_media_packet_info->first_abs_ts);
+ pitem = proto_tree_add_double(sbc_tree, hf_sbc_delta_time_from_the_beginning, tvb, offset, 0, nstime_to_msec(&delta));
+ proto_item_append_text(pitem, " ms");
+ PROTO_ITEM_SET_GENERATED(pitem);
+
+ if (!pinfo->fd->flags.visited)
+ info->current_media_packet_info->cummulative_frame_duration += cummulative_frame_duration;
+
+ pitem = proto_tree_add_double(sbc_tree, hf_sbc_cummulative_duration, tvb, offset, 0, info->previous_media_packet_info->cummulative_frame_duration);
+ proto_item_append_text(pitem, " ms");
+ PROTO_ITEM_SET_GENERATED(pitem);
+
+ pitem = proto_tree_add_double(sbc_tree, hf_sbc_diff, tvb, offset, 0, info->previous_media_packet_info->cummulative_frame_duration - nstime_to_msec(&delta));
+ proto_item_append_text(pitem, " ms");
+ PROTO_ITEM_SET_GENERATED(pitem);
+ }
+
/* TODO: more precise dissection: blocks, channels, subbands, padding */
col_append_fstr(pinfo->cinfo, COL_INFO, " Frames=%u", number_of_frames);
@@ -299,9 +350,43 @@ proto_register_sbc(void)
FT_UINT8, BASE_HEX, NULL, 0x00,
NULL, HFILL }
},
-
+ { &hf_sbc_expected_data_speed,
+ { "Expected data speed", "sbc.expected_speed_data",
+ FT_UINT32, BASE_DEC, NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_sbc_frame_duration,
+ { "Frame Duration", "sbc.frame_duration",
+ FT_DOUBLE, BASE_NONE, NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_sbc_cummulative_frame_duration,
+ { "Cummulative Frame Duration", "sbc.cummulative_frame_duration",
+ FT_DOUBLE, BASE_NONE, NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_sbc_delta_time,
+ { "Delta time", "sbc.delta_time",
+ FT_DOUBLE, BASE_NONE, NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_sbc_delta_time_from_the_beginning,
+ { "Delta time from the beginning", "sbc.delta_time_from_the_beginning",
+ FT_DOUBLE, BASE_NONE, NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_sbc_cummulative_duration,
+ { "Cummulative Music Duration", "sbc.cummulative_music_duration",
+ FT_DOUBLE, BASE_NONE, NULL, 0x00,
+ NULL, HFILL }
+ },
+ { &hf_sbc_diff,
+ { "Diff", "sbc.diff",
+ FT_DOUBLE, BASE_NONE, NULL, 0x00,
+ NULL, HFILL }
+ },
{ &hf_sbc_data,
- { "Data", "sbc.data",
+ { "Frame Data", "sbc.data",
FT_NONE, BASE_NONE, NULL, 0x00,
NULL, HFILL }
},