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>
This commit is contained in:
parent
ad1977bc19
commit
f1dee59d66
|
@ -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 \
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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:
|
||||
*/
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue