diff options
author | Michal Labedzki <michal.labedzki@tieto.com> | 2014-03-27 07:59:16 +0100 |
---|---|---|
committer | Michal Labedzki <michal.labedzki@tieto.com> | 2014-05-30 11:24:19 +0000 |
commit | 32e66a4cc663e5ec351872f6d4445d2b8c53a071 (patch) | |
tree | c986d23c29c5bfd5367892bdda33b2160a7673e9 /epan | |
parent | 788228428eab63a794f029e4ba6ee3b641943a36 (diff) | |
download | wireshark-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.c | 103 | ||||
-rw-r--r-- | epan/dissectors/packet-btavdtp.h | 12 | ||||
-rw-r--r-- | epan/dissectors/packet-rtp.c | 2 | ||||
-rw-r--r-- | epan/dissectors/packet-sbc.c | 95 |
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 } }, |