diff options
author | Michal Labedzki <michal.labedzki@tieto.com> | 2014-11-12 11:57:12 +0100 |
---|---|---|
committer | Michal Labedzki <michal.labedzki@tieto.com> | 2014-11-14 10:28:22 +0000 |
commit | f1dee59d6661dc9538819209607e7884c45049b9 (patch) | |
tree | ee6911c2f2d620fbb6d69cb0433ac5880fd26262 | |
parent | ad1977bc197b9695d05f11f4975d0aa27d10c90b (diff) |
Bluetooth: A2DP: Add AVRCP song position indicator
"sbc.avrcp_song_position" can be used to determine time synchronization
between AVRCP and A2DP. It is updated on every
AVRCP PlaybackPositionChanged. Also provide version for aptx.
Change-Id: I48cd49f0fee54131a738290e2a70a24d33ba1d22
Reviewed-on: https://code.wireshark.org/review/5290
Reviewed-by: Michal Labedzki <michal.labedzki@tieto.com>
-rw-r--r-- | epan/dissectors/Makefile.common | 1 | ||||
-rw-r--r-- | epan/dissectors/packet-btavdtp.c | 39 | ||||
-rw-r--r-- | epan/dissectors/packet-btavdtp.h | 1 | ||||
-rw-r--r-- | epan/dissectors/packet-btavrcp.c | 34 | ||||
-rw-r--r-- | epan/dissectors/packet-btavrcp.h | 48 | ||||
-rw-r--r-- | epan/dissectors/packet-sbc.c | 14 |
6 files changed, 131 insertions, 6 deletions
diff --git a/epan/dissectors/Makefile.common b/epan/dissectors/Makefile.common index aff01fcd8d..5d67f1ebb8 100644 --- a/epan/dissectors/Makefile.common +++ b/epan/dissectors/Makefile.common @@ -1381,6 +1381,7 @@ DISSECTOR_INCLUDES = \ packet-bssgp.h \ packet-btavctp.h \ packet-btavdtp.h \ + packet-btavrcp.h \ packet-bthci_acl.h \ packet-btl2cap.h \ packet-btle.h \ diff --git a/epan/dissectors/packet-btavdtp.c b/epan/dissectors/packet-btavdtp.c index 06e2805d27..db4eb3a197 100644 --- a/epan/dissectors/packet-btavdtp.c +++ b/epan/dissectors/packet-btavdtp.c @@ -34,6 +34,7 @@ #include "packet-btsdp.h" #include "packet-btavdtp.h" #include "packet-rtp.h" +#include "packet-btavrcp.h" #define AVDTP_MESSAGE_TYPE_MASK 0x03 #define AVDTP_PACKET_TYPE_MASK 0x0C @@ -354,6 +355,7 @@ static int proto_aptx = -1; static int hf_aptx_data = -1; static int hf_aptx_cummulative_frame_duration = -1; static int hf_aptx_delta_time = -1; +static int hf_aptx_avrcp_song_position = -1; static int hf_aptx_delta_time_from_the_beginning = -1; static int hf_aptx_cummulative_duration = -1; static int hf_aptx_diff = -1; @@ -1382,6 +1384,8 @@ dissect_btavdtp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) media_packet_info_t *current_media_packet_info; nstime_t first_abs_ts; gdouble cummulative_frame_duration; + gdouble avrcp_song_position = -1.0; + btavrcp_song_position_data_t *song_position_data; sep_data.codec = channels_info->sep->codec; sep_data.vendor_id = channels_info->sep->vendor_id; @@ -1410,19 +1414,41 @@ dissect_btavdtp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) key[5].length = 0; key[5].key = NULL; + key[2].length = 0; + key[2].key = NULL; + + subtree = (wmem_tree_t *) wmem_tree_lookup32_array(btavrcp_song_positions, key); + song_position_data = (subtree) ? (btavrcp_song_position_data_t *) wmem_tree_lookup32_le(subtree, frame_number) : NULL; + if (song_position_data && (song_position_data->used_in_frame == 0 || + song_position_data->used_in_frame == frame_number)) { + avrcp_song_position = song_position_data->song_position; + if (!pinfo->fd->flags.visited) + song_position_data->used_in_frame = frame_number; + } + + key[2].length = 1; + key[2].key = &chandle; + 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 && previous_media_packet_info->stream_number == sep_data.stream_number ) { 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; + if (avrcp_song_position == -1.0) + avrcp_song_position = previous_media_packet_info->avrcp_song_position; + else + previous_media_packet_info->avrcp_song_position = avrcp_song_position; } else { + if (avrcp_song_position == -1.0) + avrcp_song_position = 0.0; 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; + sep_data.previous_media_packet_info->avrcp_song_position = avrcp_song_position; sep_data.previous_media_packet_info->stream_number = sep_data.stream_number; } @@ -1432,10 +1458,14 @@ dissect_btavdtp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) key[6].length = 0; key[6].key = NULL; + if (avrcp_song_position == -1.0) + avrcp_song_position = 0.0; + 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; + current_media_packet_info->avrcp_song_position = avrcp_song_position; current_media_packet_info->stream_number = sep_data.stream_number; wmem_tree_insert32_array(media_packet_times, key, current_media_packet_info); @@ -2665,6 +2695,10 @@ dissect_aptx(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) proto_item_append_text(pitem, " ms"); PROTO_ITEM_SET_GENERATED(pitem); + pitem = proto_tree_add_double(aptx_tree, hf_aptx_avrcp_song_position, tvb, 0, 0, info->previous_media_packet_info->avrcp_song_position); + 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(aptx_tree, hf_aptx_delta_time_from_the_beginning, tvb, 0, 0, nstime_to_msec(&delta)); proto_item_append_text(pitem, " ms"); @@ -2704,6 +2738,11 @@ proto_register_aptx(void) FT_DOUBLE, BASE_NONE, NULL, 0x00, NULL, HFILL } }, + { &hf_aptx_avrcp_song_position, + { "AVRCP Song Position", "aptx.avrcp_song_position", + FT_DOUBLE, BASE_NONE, NULL, 0x00, + NULL, HFILL } + }, { &hf_aptx_delta_time_from_the_beginning, { "Delta time from the beginning", "aptx.delta_time_from_the_beginning", FT_DOUBLE, BASE_NONE, NULL, 0x00, diff --git a/epan/dissectors/packet-btavdtp.h b/epan/dissectors/packet-btavdtp.h index 2f16e59673..2371ffc646 100644 --- a/epan/dissectors/packet-btavdtp.h +++ b/epan/dissectors/packet-btavdtp.h @@ -31,6 +31,7 @@ typedef struct _media_packet_info_t { nstime_t abs_ts; nstime_t first_abs_ts; gdouble cummulative_frame_duration; + gdouble avrcp_song_position; guint32 stream_number; } media_packet_info_t; diff --git a/epan/dissectors/packet-btavrcp.c b/epan/dissectors/packet-btavrcp.c index 195d7b665a..eb0c6edd40 100644 --- a/epan/dissectors/packet-btavrcp.c +++ b/epan/dissectors/packet-btavrcp.c @@ -34,6 +34,7 @@ #include "packet-btl2cap.h" #include "packet-btsdp.h" #include "packet-btavctp.h" +#include "packet-btavrcp.h" static int proto_btavrcp = -1; @@ -272,8 +273,9 @@ static dissector_handle_t btavrcp_handle; #define STATUS_OK 0x04 -static wmem_tree_t *reassembling = NULL; -static wmem_tree_t *timing = NULL; +static wmem_tree_t *reassembling = NULL; +static wmem_tree_t *timing = NULL; + wmem_tree_t *btavrcp_song_positions = NULL; typedef struct _fragment { guint start_frame_number; @@ -307,7 +309,7 @@ typedef struct _timing_info { guint32 opcode; guint32 op; guint32 op_arg; - } timing_info_t; +} timing_info_t; static const value_string packet_type_vals[] = { { PACKET_TYPE_SINGLE, "Single" }, @@ -1592,6 +1594,27 @@ dissect_vendor_dependant(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, if (song_position == 0xFFFFFFFF) { proto_item_append_text(pitem, " (NOT SELECTED)"); col_append_str(pinfo->cinfo, COL_INFO, " (NOT SELECTED)"); + } else if (!pinfo->fd->flags.visited) { + btavrcp_song_position_data_t *song_position_data; + + k_interface_id = interface_id; + k_adapter_id = adapter_id; + k_frame_number = pinfo->fd->num; + + key[0].length = 1; + key[0].key = &k_interface_id; + key[1].length = 1; + key[1].key = &k_adapter_id; + key[2].length = 1; + key[2].key = &k_frame_number; + key[3].length = 0; + key[3].key = NULL; + + song_position_data = wmem_new(wmem_file_scope(), btavrcp_song_position_data_t); + song_position_data->song_position = song_position; + song_position_data->used_in_frame = 0; + + wmem_tree_insert32_array(btavrcp_song_positions, key, song_position_data); } break; case EVENT_BATTERY_STATUS_CHANGED: @@ -3162,8 +3185,9 @@ proto_register_btavrcp(void) { &ei_btavrcp_no_response, { "btavrcp.no_response", PI_PROTOCOL, PI_WARN, "No response", EXPFILL }}, }; - reassembling = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope()); - timing = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope()); + reassembling = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope()); + timing = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope()); + btavrcp_song_positions = wmem_tree_new_autoreset(wmem_epan_scope(), wmem_file_scope()); proto_btavrcp = proto_register_protocol("Bluetooth AVRCP Profile", "BT AVRCP", "btavrcp"); btavrcp_handle = new_register_dissector("btavrcp", dissect_btavrcp, proto_btavrcp); diff --git a/epan/dissectors/packet-btavrcp.h b/epan/dissectors/packet-btavrcp.h new file mode 100644 index 0000000000..3e79a915cf --- /dev/null +++ b/epan/dissectors/packet-btavrcp.h @@ -0,0 +1,48 @@ +/* packet-btavrcp.h + * Headers for AVRCP + * + * Copyright 2014, Michal Labedzki for Tieto Corporation + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef __PACKET_BTAVRCP_H__ +#define __PACKET_BTAVRCP_H__ + +wmem_tree_t *btavrcp_song_positions; + +typedef struct _btavrcp_song_position_data_t { + guint32 song_position; + guint32 used_in_frame; +} btavrcp_song_position_data_t; + +#endif + +/* + * Editor modelines - http://www.wireshark.org/tools/modelines.html + * + * Local variables: + * c-basic-offset: 4 + * tab-width: 8 + * indent-tabs-mode: nil + * End: + * + * vi: set shiftwidth=4 tabstop=8 expandtab: + * :indentSize=4:tabSize=8:noTabs=true: + */ diff --git a/epan/dissectors/packet-sbc.c b/epan/dissectors/packet-sbc.c index 8e57f58942..b308be1083 100644 --- a/epan/dissectors/packet-sbc.c +++ b/epan/dissectors/packet-sbc.c @@ -62,6 +62,7 @@ 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_avrcp_song_position = -1; static int hf_sbc_diff = -1; static int hf_sbc_data = -1; @@ -252,13 +253,19 @@ dissect_sbc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) proto_item_append_text(pitem, " ms"); PROTO_ITEM_SET_GENERATED(pitem); + pitem = proto_tree_add_double(sbc_tree, hf_sbc_avrcp_song_position, tvb, offset, 0, info->previous_media_packet_info->avrcp_song_position); + 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) + if (!pinfo->fd->flags.visited) { info->current_media_packet_info->cummulative_frame_duration += cummulative_frame_duration; + info->current_media_packet_info->avrcp_song_position += 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"); @@ -378,6 +385,11 @@ proto_register_sbc(void) FT_DOUBLE, BASE_NONE, NULL, 0x00, NULL, HFILL } }, + { &hf_sbc_avrcp_song_position, + { "AVRCP Song Position", "sbc.avrcp_song_position", + FT_DOUBLE, BASE_NONE, NULL, 0x00, + NULL, HFILL } + }, { &hf_sbc_diff, { "Diff", "sbc.diff", FT_DOUBLE, BASE_NONE, NULL, 0x00, |