aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichal Labedzki <michal.labedzki@tieto.com>2014-11-12 11:57:12 +0100
committerMichal Labedzki <michal.labedzki@tieto.com>2014-11-14 10:28:22 +0000
commitf1dee59d6661dc9538819209607e7884c45049b9 (patch)
treeee6911c2f2d620fbb6d69cb0433ac5880fd26262
parentad1977bc197b9695d05f11f4975d0aa27d10c90b (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.common1
-rw-r--r--epan/dissectors/packet-btavdtp.c39
-rw-r--r--epan/dissectors/packet-btavdtp.h1
-rw-r--r--epan/dissectors/packet-btavrcp.c34
-rw-r--r--epan/dissectors/packet-btavrcp.h48
-rw-r--r--epan/dissectors/packet-sbc.c14
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,