aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--epan/dissectors/packet-btavdtp.c343
-rw-r--r--epan/dissectors/packet-btavdtp.h12
-rw-r--r--epan/dissectors/packet-hci_h1.c2
-rw-r--r--epan/dissectors/packet-hci_h4.c2
-rw-r--r--epan/dissectors/packet-rtp.c272
-rw-r--r--epan/dissectors/packet-rtp.h19
-rw-r--r--ui/rtp_stream.h2
-rw-r--r--ui/tap-rtp-common.c2
8 files changed, 534 insertions, 120 deletions
diff --git a/epan/dissectors/packet-btavdtp.c b/epan/dissectors/packet-btavdtp.c
index a316080297..b86bfc6af3 100644
--- a/epan/dissectors/packet-btavdtp.c
+++ b/epan/dissectors/packet-btavdtp.c
@@ -34,6 +34,7 @@
#include "packet-btl2cap.h"
#include "packet-btsdp.h"
#include "packet-btavdtp.h"
+#include "packet-rtp.h"
#define AVDTP_MESSAGE_TYPE_MASK 0x03
#define AVDTP_PACKET_TYPE_MASK 0x0C
@@ -250,21 +251,58 @@ static wmem_tree_t *sep_open = NULL;
static wmem_tree_t *cid_to_type_table = NULL;
/* A2DP declarations */
-static int proto_bta2dp = -1;
-static gint ett_bta2dp = -1;
+static gint proto_bta2dp = -1;
+static gint ett_bta2dp = -1;
+static gint proto_bta2dp_cph_scms_t = -1;
+static gint ett_bta2dp_cph_scms_t = -1;
+
+static int hf_bta2dp_codec = -1;
+static int hf_bta2dp_content_protection = -1;
+static int hf_bta2dp_l_bit = -1;
+static int hf_bta2dp_cp_bit = -1;
+static int hf_bta2dp_reserved = -1;
static dissector_handle_t sbc_handle;
static dissector_handle_t mp2t_handle;
static dissector_handle_t mpeg_audio_handle;
static dissector_handle_t atrac_handle;
+static gboolean force_a2dp_scms_t = FALSE;
+static gint force_a2dp_codec = CODEC_SBC;
+
+static const enum_val_t pref_a2dp_codec[] = {
+ { "sbc", "SBC", CODEC_SBC },
+ { "mp2t", "MPEG12 AUDIO", CODEC_MPEG12_AUDIO },
+ { "mpeg-audio", "MPEG24 AAC", CODEC_MPEG24_AAC },
+/* XXX: Not supported in Wireshark yet { "atrac", "ATRAC", CODEC_ATRAC },*/
+ { NULL, NULL, 0 }
+};
+
+
/* VDP declarations */
-static int proto_btvdp = -1;
-static gint ett_btvdp = -1;
+static gint proto_btvdp = -1;
+static gint ett_btvdp = -1;
+static gint proto_btvdp_cph_scms_t = -1;
+static gint ett_btvdp_cph_scms_t = -1;
+
+static int hf_btvdp_codec = -1;
+static int hf_btvdp_content_protection = -1;
+static int hf_btvdp_l_bit = -1;
+static int hf_btvdp_cp_bit = -1;
+static int hf_btvdp_reserved = -1;
static dissector_handle_t h263_handle;
static dissector_handle_t mp4v_es_handle;
+static gboolean force_vdp_scms_t = FALSE;
+static gint force_vdp_codec = CODEC_H263_BASELINE;
+
+static const enum_val_t pref_vdp_codec[] = {
+ { "h263", "H263", CODEC_H263_BASELINE },
+ { "mp4v-es", "MPEG4 VSP", CODEC_MPEG4_VSP },
+ { NULL, NULL, 0 }
+};
+
static const value_string message_type_vals[] = {
{ 0x00, "Command" },
@@ -392,6 +430,12 @@ static const value_string media_codec_video_type_vals[] = {
{ 0, NULL }
};
+static const value_string content_protection_type_vals[] = {
+ { 0x01, "DTCP" },
+ { 0x02, "SCMS-T" },
+ { 0, NULL }
+};
+
extern value_string_ext bthci_evt_comp_id_ext;
enum sep_state {
@@ -405,6 +449,7 @@ typedef struct _sep_entry_t {
guint8 type;
guint8 media_type;
gint codec;
+ gint content_protection_type;
enum sep_state state;
} sep_entry_t;
@@ -414,12 +459,20 @@ typedef struct _cid_type_data_t {
sep_entry_t *sep;
} cid_type_data_t;
+
+typedef struct _sep_data_t {
+ gint codec;
+ gint content_protection_type;
+} sep_data_t;
+
void proto_register_btavdtp(void);
void proto_reg_handoff_btavdtp(void);
void proto_register_bta2dp(void);
void proto_reg_handoff_bta2dp(void);
+void proto_register_bta2dp_content_protection_header_scms_t(void);
void proto_register_btvdp(void);
void proto_reg_handoff_btvdp(void);
+void proto_register_btvdp_content_protection_header_scms_t(void);
static const char *
get_sep_type(guint32 frame_number, guint seid)
@@ -527,6 +580,7 @@ dissect_sep(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
sep_data->seid = seid;
sep_data->type = type;
sep_data->codec = -1;
+ sep_data->content_protection_type = 0;
sep_data->media_type = media_type;
if (in_use) {
sep_data->state = SEP_STATE_IN_USE;
@@ -700,7 +754,8 @@ dissect_codec(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset,
static gint
dissect_capabilities(tvbuff_t *tvb, packet_info *pinfo,
- proto_tree *tree, gint offset, gint *codec)
+ proto_tree *tree, gint offset, gint *codec,
+ gint *content_protection_type)
{
proto_item *pitem = NULL;
proto_item *ptree = NULL;
@@ -805,13 +860,19 @@ dissect_capabilities(tvbuff_t *tvb, packet_info *pinfo,
losc = 0;
break;
case SERVICE_CATEGORY_CONTENT_PROTECTION:
+ /* ENC_LITTLE_ENDIAN is correct here... */
proto_tree_add_item(service_tree, hf_btavdtp_content_protection_type, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ if (content_protection_type) {
+ *content_protection_type = tvb_get_letohs(tvb, offset);
+ }
offset += 2;
losc -= 2;
- proto_tree_add_item(service_tree, hf_btavdtp_data, tvb, offset, losc, ENC_NA);
- offset += losc;
- losc = 0;
+ if (losc > 0) {
+ proto_tree_add_item(service_tree, hf_btavdtp_data, tvb, offset, losc, ENC_NA);
+ offset += losc;
+ losc = 0;
+ }
break;
case SERVICE_CATEGORY_HEADER_COMPRESSION:
proto_tree_add_item(service_tree, hf_btavdtp_header_compression_backch, tvb, offset, 1, ENC_BIG_ENDIAN);
@@ -950,7 +1011,8 @@ dissect_btavdtp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
tvbuff_t *next_tvb;
guint32 seid;
guint32 t_seid;
- gint codec;
+ gint codec = -1;
+ gint content_protection_type = 0;
col_set_str(pinfo->cinfo, COL_PROTOCOL, "AVDTP");
@@ -1047,11 +1109,21 @@ dissect_btavdtp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
get_sep_type(pinfo->fd->num, cid_type_data->sep->seid));
if (cid_type_data->sep->media_type == MEDIA_TYPE_AUDIO) {
+ sep_data_t sep_data;
+
+ sep_data.codec = cid_type_data->sep->codec;
+ sep_data.content_protection_type = cid_type_data->sep->content_protection_type;
+
next_tvb = tvb_new_subset_remaining(tvb, offset);
- call_dissector_with_data(bta2dp_handle, next_tvb, pinfo, tree, &cid_type_data->sep->codec);
+ call_dissector_with_data(bta2dp_handle, next_tvb, pinfo, tree, &sep_data);
} else if (cid_type_data->sep->media_type == MEDIA_TYPE_VIDEO) {
+ sep_data_t sep_data;
+
+ sep_data.codec = cid_type_data->sep->codec;
+ sep_data.content_protection_type = cid_type_data->sep->content_protection_type;
+
next_tvb = tvb_new_subset_remaining(tvb, offset);
- call_dissector_with_data(btvdp_handle, next_tvb, pinfo, tree, &cid_type_data->sep->codec);
+ call_dissector_with_data(btvdp_handle, next_tvb, pinfo, tree, &sep_data);
} else {
ti = proto_tree_add_item(tree, proto_btavdtp, tvb, offset, -1, ENC_NA);
btavdtp_tree = proto_item_add_subtree(ti, ett_btavdtp);
@@ -1129,13 +1201,13 @@ dissect_btavdtp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
proto_tree_add_item(btavdtp_tree, hf_btavdtp_error_code, tvb, offset, 1, ENC_BIG_ENDIAN);
break;
}
- offset = dissect_capabilities(tvb, pinfo, btavdtp_tree, offset, NULL);
+ offset = dissect_capabilities(tvb, pinfo, btavdtp_tree, offset, NULL, NULL);
break;
case SIGNAL_ID_SET_CONFIGURATION:
if (message_type == MESSAGE_TYPE_COMMAND) {
offset = dissect_seid(tvb, pinfo, btavdtp_tree, offset, SEID_ACP, 0, &seid);
offset = dissect_seid(tvb, pinfo, btavdtp_tree, offset, SEID_INT, 0, NULL);
- offset = dissect_capabilities(tvb, pinfo, btavdtp_tree, offset, &codec);
+ offset = dissect_capabilities(tvb, pinfo, btavdtp_tree, offset, &codec, &content_protection_type);
t_frame_number = pinfo->fd->num;
t_seid = seid;
@@ -1150,6 +1222,7 @@ dissect_btavdtp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
sep = (sep_entry_t *)wmem_tree_lookup32_array_le(sep_list, key);
if (sep && sep->seid == seid) {
sep->codec = codec;
+ sep->content_protection_type = content_protection_type;
}
break;
@@ -1170,12 +1243,12 @@ dissect_btavdtp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
proto_tree_add_item(btavdtp_tree, hf_btavdtp_error_code, tvb, offset, 1, ENC_BIG_ENDIAN);
break;
}
- offset = dissect_capabilities(tvb, pinfo, btavdtp_tree, offset, NULL);
+ offset = dissect_capabilities(tvb, pinfo, btavdtp_tree, offset, NULL, NULL);
break;
case SIGNAL_ID_RECONFIGURE:
if (message_type == MESSAGE_TYPE_COMMAND) {
offset = dissect_seid(tvb, pinfo, btavdtp_tree, offset, SEID_ACP, 0, &seid);
- offset = dissect_capabilities(tvb, pinfo, btavdtp_tree, offset, &codec);
+ offset = dissect_capabilities(tvb, pinfo, btavdtp_tree, offset, &codec, &content_protection_type);
t_frame_number = pinfo->fd->num;
t_seid = seid;
@@ -1190,6 +1263,7 @@ dissect_btavdtp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
sep = (sep_entry_t *)wmem_tree_lookup32_array_le(sep_list, key);
if (sep && sep->seid == seid) {
sep->codec = codec;
+ sep->content_protection_type = content_protection_type;
}
break;
@@ -1504,7 +1578,7 @@ proto_register_btavdtp(void)
},
{ &hf_btavdtp_content_protection_type,
{ "Type", "btavdtp.content_protection_type",
- FT_UINT16, BASE_HEX, NULL, 0x0000,
+ FT_UINT16, BASE_HEX, VALS(content_protection_type_vals), 0x0000,
NULL, HFILL }
},
{ &hf_btavdtp_media_codec_media_type,
@@ -2013,14 +2087,28 @@ dissect_bta2dp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
proto_item *ti;
proto_tree *bta2dp_tree;
proto_item *pitem;
- gint offset = 0;
- gint codec = -1;
- void *save_private_data;
- dissector_handle_t codec_dissector = NULL;
- btavdtp_data_t *btavdtp_data;
-
- if (data)
- codec = *((gint *) data);
+ gint offset = 0;
+ dissector_handle_t codec_dissector = NULL;
+ bta2dp_codec_info_t bta2dp_codec_info;
+ sep_data_t sep_data;
+
+ sep_data.codec = CODEC_SBC;
+ sep_data.content_protection_type = 0;
+
+ if (force_a2dp_scms_t || force_a2dp_codec) {
+ if (force_a2dp_scms_t)
+ sep_data.content_protection_type = 2;
+ else if (data)
+ sep_data.content_protection_type = ((sep_data_t *) data)->content_protection_type;
+
+ if (force_a2dp_codec)
+ sep_data.codec = force_a2dp_codec;
+ else if (data)
+ sep_data.codec = ((sep_data_t *) data)->codec;
+ } else {
+ if (data)
+ sep_data = *((sep_data_t *) data);
+ }
col_set_str(pinfo->cinfo, COL_PROTOCOL, "A2DP");
@@ -2046,15 +2134,19 @@ dissect_bta2dp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
ti = proto_tree_add_item(tree, proto_bta2dp, tvb, offset, -1, ENC_NA);
col_append_fstr(pinfo->cinfo, COL_INFO, "Audio stream - %s",
- val_to_str_const(codec, media_codec_audio_type_vals, "unknown codec"));
+ val_to_str_const(sep_data.codec, media_codec_audio_type_vals, "unknown codec"));
bta2dp_tree = proto_item_add_subtree(ti, ett_bta2dp);
- pitem = proto_tree_add_text(bta2dp_tree, tvb, offset, tvb_length_remaining(tvb, offset), "Codec: %s",
- val_to_str_const(codec, media_codec_audio_type_vals, "unknown codec"));
+ pitem = proto_tree_add_uint(bta2dp_tree, hf_bta2dp_codec, tvb, offset, 0, sep_data.codec);
PROTO_ITEM_SET_GENERATED(pitem);
- switch (codec) {
+ if (sep_data.content_protection_type > 0) {
+ pitem = proto_tree_add_uint(bta2dp_tree, hf_bta2dp_content_protection, tvb, offset, 0, sep_data.content_protection_type);
+ PROTO_ITEM_SET_GENERATED(pitem);
+ }
+
+ switch (sep_data.codec) {
case CODEC_SBC:
codec_dissector = sbc_handle;
break;
@@ -2069,18 +2161,13 @@ dissect_bta2dp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
break;
}
- save_private_data = pinfo->private_data;
-
- btavdtp_data = wmem_new(wmem_packet_scope(), btavdtp_data_t);
- btavdtp_data->codec_dissector = codec_dissector;
-
- pinfo->private_data = btavdtp_data;
+ bta2dp_codec_info.codec_dissector = codec_dissector;
+ bta2dp_codec_info.content_protection_type = sep_data.content_protection_type;
+ bluetooth_add_address(pinfo, &pinfo->net_dst, "BT A2DP", pinfo->fd->num, FALSE, &bta2dp_codec_info);
call_dissector(rtp_handle, tvb, pinfo, tree);
offset += tvb_length_remaining(tvb, offset);
- pinfo->private_data = save_private_data;
-
return offset;
}
@@ -2088,7 +2175,7 @@ void
proto_register_bta2dp(void)
{
module_t *module;
-#if 0
+
static hf_register_info hf[] = {
{ &hf_bta2dp_codec,
{ "Codec", "bta2dp.codec",
@@ -2101,16 +2188,13 @@ proto_register_bta2dp(void)
NULL, HFILL }
}
};
-#endif
static gint *ett[] = {
&ett_bta2dp
};
proto_bta2dp = proto_register_protocol("Bluetooth A2DP Profile", "BT A2DP", "bta2dp");
-#if 0
proto_register_field_array(proto_bta2dp, hf, array_length(hf));
-#endif
proto_register_subtree_array(ett, array_length(ett));
new_register_dissector("bta2dp", dissect_bta2dp, proto_bta2dp);
@@ -2119,6 +2203,16 @@ proto_register_bta2dp(void)
prefs_register_static_text_preference(module, "a2dp.version",
"Bluetooth Profile A2DP version: 1.3",
"Version of profile supported by this dissector.");
+
+ prefs_register_bool_preference(module, "a2dp.content_protection.scms_t",
+ "Force SCMS-T decoding",
+ "Force decoding stream as A2DP with Content Protection SCMS-T ",
+ &force_a2dp_scms_t);
+
+ prefs_register_enum_preference(module, "a2dp.codec",
+ "Force codec",
+ "Force decoding stream as A2DP with specified codec",
+ &force_a2dp_codec, pref_a2dp_codec, FALSE);
}
void
@@ -2139,21 +2233,34 @@ proto_reg_handoff_bta2dp(void)
dissector_add_handle("btl2cap.cid", bta2dp_handle);
}
-
static gint
dissect_btvdp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
{
proto_item *ti;
proto_tree *btvdp_tree;
proto_item *pitem;
- gint offset = 0;
- gint codec = -1;
- void *save_private_data;
- dissector_handle_t codec_dissector = NULL;
- btavdtp_data_t *btavdtp_data;
-
- if (data)
- codec = *((gint *) data);
+ gint offset = 0;
+ dissector_handle_t codec_dissector = NULL;
+ btvdp_codec_info_t btvdp_codec_info;
+ sep_data_t sep_data;
+
+ sep_data.codec = CODEC_H263_BASELINE;
+ sep_data.content_protection_type = 0;
+
+ if (force_vdp_scms_t || force_vdp_codec) {
+ if (force_vdp_scms_t)
+ sep_data.content_protection_type = 2;
+ else if (data)
+ sep_data.content_protection_type = ((sep_data_t *) data)->content_protection_type;
+
+ if (force_vdp_codec)
+ sep_data.codec = force_vdp_codec;
+ else if (data)
+ sep_data.codec = ((sep_data_t *) data)->codec;
+ } else {
+ if (data)
+ sep_data = *((sep_data_t *) data);
+ }
col_set_str(pinfo->cinfo, COL_PROTOCOL, "VDP");
@@ -2179,15 +2286,19 @@ dissect_btvdp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
ti = proto_tree_add_item(tree, proto_btvdp, tvb, offset, -1, ENC_NA);
col_append_fstr(pinfo->cinfo, COL_INFO, "Video stream - %s",
- val_to_str_const(codec, media_codec_video_type_vals, "unknown codec"));
+ val_to_str_const(sep_data.codec, media_codec_video_type_vals, "unknown codec"));
btvdp_tree = proto_item_add_subtree(ti, ett_btvdp);
- pitem = proto_tree_add_text(btvdp_tree, tvb, offset, tvb_length_remaining(tvb, offset), "Codec: %s",
- val_to_str_const(codec, media_codec_video_type_vals, "unknown codec"));
+ pitem = proto_tree_add_uint(btvdp_tree, hf_btvdp_codec, tvb, offset, 0, sep_data.codec);
PROTO_ITEM_SET_GENERATED(pitem);
- switch (codec) {
+ if (sep_data.content_protection_type > 0) {
+ pitem = proto_tree_add_uint(btvdp_tree, hf_btvdp_content_protection, tvb, offset, 0, sep_data.content_protection_type);
+ PROTO_ITEM_SET_GENERATED(pitem);
+ }
+
+ switch (sep_data.codec) {
case CODEC_H263_BASELINE:
case CODEC_H263_PROFILE_3:
case CODEC_H263_PROFILE_8:
@@ -2198,18 +2309,13 @@ dissect_btvdp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
break;
}
- save_private_data = pinfo->private_data;
-
- btavdtp_data = wmem_new(wmem_packet_scope(), btavdtp_data_t);
- btavdtp_data->codec_dissector = codec_dissector;
-
- pinfo->private_data = btavdtp_data;
+ btvdp_codec_info.codec_dissector = codec_dissector;
+ btvdp_codec_info.content_protection_type = sep_data.content_protection_type;
+ bluetooth_add_address(pinfo, &pinfo->net_dst, "BT VDP", pinfo->fd->num, TRUE, &btvdp_codec_info);
call_dissector(rtp_handle, tvb, pinfo, tree);
offset += tvb_length_remaining(tvb, offset);
- pinfo->private_data = save_private_data;
-
return offset;
}
@@ -2219,7 +2325,6 @@ proto_register_btvdp(void)
module_t *module;
expert_module_t* expert_btavdtp;
-#if 0
static hf_register_info hf[] = {
{ &hf_btvdp_codec,
{ "Codec", "btvdp.codec",
@@ -2232,7 +2337,6 @@ proto_register_btvdp(void)
NULL, HFILL }
}
};
-#endif
static gint *ett[] = {
&ett_btvdp
@@ -2246,9 +2350,7 @@ proto_register_btvdp(void)
proto_btvdp = proto_register_protocol("Bluetooth VDP Profile", "BT VDP", "btvdp");
new_register_dissector("btvdp", dissect_btvdp, proto_btvdp);
-#if 0
proto_register_field_array(proto_bta2dp, hf, array_length(hf));
-#endif
proto_register_subtree_array(ett, array_length(ett));
expert_btavdtp = expert_register_protocol(proto_btvdp);
expert_register_field_array(expert_btavdtp, ei, array_length(ei));
@@ -2257,6 +2359,16 @@ proto_register_btvdp(void)
prefs_register_static_text_preference(module, "vdp.version",
"Bluetooth Profile VDP version: 1.1",
"Version of profile supported by this dissector.");
+
+ prefs_register_bool_preference(module, "vdp.content_protection.scms_t",
+ "Force SCMS-T decoding",
+ "Force decoding stream as VDP with Content Protection SCMS-T ",
+ &force_vdp_scms_t);
+
+ prefs_register_enum_preference(module, "vdp.codec",
+ "Force codec",
+ "Force decoding stream as VDP with specified codec",
+ &force_vdp_codec, pref_vdp_codec, FALSE);
}
void
@@ -2275,6 +2387,107 @@ proto_reg_handoff_btvdp(void)
}
+
+static gint
+dissect_a2dp_cp_scms_t(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
+{
+ proto_item *main_item;
+ proto_tree *main_tree;
+ gint offset = 0;
+
+ main_item = proto_tree_add_item(tree, proto_bta2dp_cph_scms_t, tvb, offset, 1, ENC_NA);
+ main_tree = proto_item_add_subtree(main_item, ett_bta2dp_cph_scms_t);
+
+ proto_tree_add_item(main_tree, hf_bta2dp_reserved , tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(main_tree, hf_bta2dp_cp_bit, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(main_tree, hf_bta2dp_l_bit , tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset += 1;
+
+ return offset;
+}
+
+void
+proto_register_bta2dp_content_protection_header_scms_t(void)
+{
+ static hf_register_info hf[] = {
+ { &hf_bta2dp_l_bit,
+ { "L-bit", "bta2dp.content_protection_header.scms_t.l_bit",
+ FT_BOOLEAN, 8, NULL, 0x01,
+ NULL, HFILL }
+ },
+ { &hf_bta2dp_cp_bit,
+ { "Cp-bit", "bta2dp.content_protection_header.scms_t.cp_bit",
+ FT_BOOLEAN, 8, NULL, 0x02,
+ NULL, HFILL }
+ },
+ { &hf_bta2dp_reserved,
+ { "Reserved", "bta2dp.content_protection_header.scms_t.reserved",
+ FT_BOOLEAN, 8, NULL, 0xFC,
+ NULL, HFILL }
+ }
+ };
+
+ static gint *ett[] = {
+ &ett_bta2dp_cph_scms_t
+ };
+
+ proto_bta2dp_cph_scms_t = proto_register_protocol("Bluetooth A2DP Content Protection Header SCMS-T", "BT A2DP Content Protection Header SCMS-T", "bta2dp_content_protection_header_scms_t");
+ proto_register_field_array(proto_bta2dp_cph_scms_t, hf, array_length(hf));
+ proto_register_subtree_array(ett, array_length(ett));
+
+ new_register_dissector("bta2dp_content_protection_header_scms_t", dissect_a2dp_cp_scms_t, proto_bta2dp_cph_scms_t);
+}
+
+static gint
+dissect_vdp_cp_scms_t(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
+{
+ proto_item *main_item;
+ proto_tree *main_tree;
+ gint offset = 0;
+
+ main_item = proto_tree_add_item(tree, proto_btvdp_cph_scms_t, tvb, offset, 1, ENC_NA);
+ main_tree = proto_item_add_subtree(main_item, ett_btvdp_cph_scms_t);
+
+ proto_tree_add_item(main_tree, hf_btvdp_reserved , tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(main_tree, hf_btvdp_cp_bit, tvb, offset, 1, ENC_BIG_ENDIAN);
+ proto_tree_add_item(main_tree, hf_btvdp_l_bit , tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset += 1;
+
+ return offset;
+}
+
+void
+proto_register_btvdp_content_protection_header_scms_t(void)
+{
+ static hf_register_info hf[] = {
+ { &hf_btvdp_l_bit,
+ { "L-bit", "btvdp.content_protection_header.scms_t.l_bit",
+ FT_BOOLEAN, 8, NULL, 0x01,
+ NULL, HFILL }
+ },
+ { &hf_btvdp_cp_bit,
+ { "Cp-bit", "btvdp.content_protection_header.scms_t.cp_bit",
+ FT_BOOLEAN, 8, NULL, 0x02,
+ NULL, HFILL }
+ },
+ { &hf_btvdp_reserved,
+ { "Reserved", "btvdp.content_protection_header.scms_t.reserved",
+ FT_BOOLEAN, 8, NULL, 0xFC,
+ NULL, HFILL }
+ }
+ };
+
+ static gint *ett[] = {
+ &ett_btvdp_cph_scms_t
+ };
+
+ proto_btvdp_cph_scms_t = proto_register_protocol("Bluetooth VDP Content Protection Header SCMS-T", "BT VDP Content Protection Header SCMS-T", "btvdp_content_protection_header_scms_t");
+ proto_register_field_array(proto_btvdp_cph_scms_t, hf, array_length(hf));
+ proto_register_subtree_array(ett, array_length(ett));
+
+ new_register_dissector("btvdp_content_protection_header_scms_t", dissect_vdp_cp_scms_t, proto_btvdp_cph_scms_t);
+}
+
/*
* Editor modelines - http://www.wireshark.org/tools/modelines.html
*
diff --git a/epan/dissectors/packet-btavdtp.h b/epan/dissectors/packet-btavdtp.h
index c847571332..0fa9cb4e26 100644
--- a/epan/dissectors/packet-btavdtp.h
+++ b/epan/dissectors/packet-btavdtp.h
@@ -27,9 +27,17 @@
#ifndef __PACKET_BTAVDTP_H__
#define __PACKET_BTAVDTP_H__
-typedef struct _btavdtp_data_t {
+#define BTAVDTP_CONTENT_PROTECTION_TYPE_SCMS_T 0x02
+
+typedef struct _bta2dp_codec_info_t {
+ dissector_handle_t codec_dissector;
+ gint content_protection_type;
+} bta2dp_codec_info_t;
+
+typedef struct _btvdp_codec_info_t {
dissector_handle_t codec_dissector;
-} btavdtp_data_t;
+ gint content_protection_type;
+} btvdp_codec_info_t;
#endif
diff --git a/epan/dissectors/packet-hci_h1.c b/epan/dissectors/packet-hci_h1.c
index f0200b7261..a72657f6b9 100644
--- a/epan/dissectors/packet-hci_h1.c
+++ b/epan/dissectors/packet-hci_h1.c
@@ -114,6 +114,8 @@ dissect_hci_h1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _
hci_data->localhost_bdaddr = localhost_bdaddr;
hci_data->localhost_name = localhost_name;
+ pinfo->ptype = PT_BLUETOOTH;
+
ti = proto_tree_add_int(hci_h1_tree, hf_hci_h1_direction, tvb, 0, 0, pinfo->p2p_dir);
PROTO_ITEM_SET_GENERATED(ti);
diff --git a/epan/dissectors/packet-hci_h4.c b/epan/dissectors/packet-hci_h4.c
index 655a8f9ecb..1b79e3e508 100644
--- a/epan/dissectors/packet-hci_h4.c
+++ b/epan/dissectors/packet-hci_h4.c
@@ -110,6 +110,8 @@ dissect_hci_h4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _
hci_data->localhost_bdaddr = localhost_bdaddr;
hci_data->localhost_name = localhost_name;
+ pinfo->ptype = PT_BLUETOOTH;
+
ti = proto_tree_add_uint(hci_h4_tree, hf_hci_h4_direction, tvb, 0, 0, pinfo->p2p_dir);
PROTO_ITEM_SET_GENERATED(ti);
diff --git a/epan/dissectors/packet-rtp.c b/epan/dissectors/packet-rtp.c
index bb4aa81c5a..1f4b04375d 100644
--- a/epan/dissectors/packet-rtp.c
+++ b/epan/dissectors/packet-rtp.c
@@ -61,11 +61,12 @@
#include <epan/packet.h>
#include "packet-rtp.h"
+
#include <epan/rtp_pt.h>
#include <epan/conversation.h>
#include <epan/reassemble.h>
#include <epan/tap.h>
-
+#include <epan/epan_dissect.h>
#include <epan/prefs.h>
#include <epan/wmem/wmem.h>
#include <epan/strutil.h>
@@ -142,6 +143,12 @@ static dissector_handle_t zrtp_handle;
static dissector_handle_t sprt_handle;
static dissector_handle_t v150fw_handle;
+static dissector_handle_t bta2dp_content_protection_header_scms_t;
+static dissector_handle_t btvdp_content_protection_header_scms_t;
+static dissector_handle_t bta2dp_handle;
+static dissector_handle_t btvdp_handle;
+static dissector_handle_t sbc_handle;
+
static int rtp_tap = -1;
static dissector_table_t rtp_pt_dissector_table;
@@ -266,11 +273,12 @@ static gint global_rtp_version0_type = 0;
static dissector_handle_t data_handle;
/* Forward declaration we need below */
+void proto_register_rtp(void);
void proto_reg_handoff_rtp(void);
+void proto_register_pkt_ccc(void);
void proto_reg_handoff_pkt_ccc(void);
-static void dissect_rtp( tvbuff_t *tvb, packet_info *pinfo,
- proto_tree *tree );
+static gint dissect_rtp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data);
static void show_setup_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
static void get_conv_info(packet_info *pinfo, struct _rtp_info *rtp_info);
@@ -806,12 +814,94 @@ rtp_free_hash_dyn_payload(GHashTable *rtp_dyn_payload)
rtp_dyn_payload = NULL;
}
+
+void
+bluetooth_add_address(packet_info *pinfo, address *addr,
+ const gchar *setup_method, guint32 setup_frame_number,
+ gboolean is_video, void *data)
+{
+ address null_addr;
+ conversation_t* p_conv;
+ struct _rtp_conversation_info *p_conv_data = NULL;
+ /*
+ * If this isn't the first time this packet has been processed,
+ * we've already done this work, so we don't need to do it
+ * again.
+ */
+ if (pinfo->fd->flags.visited)
+ {
+ return;
+ }
+
+ SET_ADDRESS(&null_addr, AT_NONE, 0, NULL);
+
+ /*
+ * Check if the ip address and port combination is not
+ * already registered as a conversation.
+ */
+ p_conv = find_conversation(setup_frame_number, addr, &null_addr, PT_BLUETOOTH, 0, 0,
+ NO_ADDR_B | NO_PORT_B);
+
+ /*
+ * If not, create a new conversation.
+ */
+ if (!p_conv || p_conv->setup_frame != setup_frame_number) {
+ p_conv = conversation_new(setup_frame_number, addr, &null_addr, PT_BLUETOOTH, 0, 0,
+ NO_ADDR2 | NO_PORT2);
+ }
+
+ /* Set dissector */
+ conversation_set_dissector(p_conv, rtp_handle);
+
+ /*
+ * Check if the conversation has data associated with it.
+ */
+ p_conv_data = (struct _rtp_conversation_info *)conversation_get_proto_data(p_conv, proto_rtp);
+
+ /*
+ * If not, add a new data item.
+ */
+ if (! p_conv_data) {
+ /* Create conversation data */
+ p_conv_data = wmem_new(wmem_file_scope(), struct _rtp_conversation_info);
+ p_conv_data->rtp_dyn_payload = NULL;
+
+ /* start this at 0x10000 so that we cope gracefully with the
+ * first few packets being out of order (hence 0,65535,1,2,...)
+ */
+ p_conv_data->extended_seqno = 0x10000;
+ p_conv_data->rtp_conv_info = wmem_new(wmem_file_scope(), rtp_private_conv_info);
+ p_conv_data->rtp_conv_info->multisegment_pdus = wmem_tree_new(wmem_file_scope());
+ conversation_add_proto_data(p_conv, proto_rtp, p_conv_data);
+
+ if (is_video) {
+ p_conv_data->bta2dp_info = NULL;
+ p_conv_data->btvdp_info = (btvdp_codec_info_t *) wmem_memdup(wmem_file_scope(), data, sizeof(btvdp_codec_info_t));
+ } else {
+ p_conv_data->bta2dp_info = (bta2dp_codec_info_t *) wmem_memdup(wmem_file_scope(), data, sizeof(bta2dp_codec_info_t));
+ p_conv_data->btvdp_info = NULL;
+ }
+ }
+
+ /*
+ * Update the conversation data.
+ */
+ /* Free the hash if already exists */
+ rtp_free_hash_dyn_payload(p_conv_data->rtp_dyn_payload);
+
+ g_strlcpy(p_conv_data->method, setup_method, MAX_RTP_SETUP_METHOD_SIZE+1);
+ p_conv_data->frame_number = setup_frame_number;
+ p_conv_data->is_video = is_video;
+ p_conv_data->rtp_dyn_payload = NULL;
+ p_conv_data->srtp_info = NULL;
+}
+
/* Set up an SRTP conversation */
void
srtp_add_address(packet_info *pinfo, address *addr, int port, int other_port,
const gchar *setup_method, guint32 setup_frame_number,
gboolean is_video _U_, GHashTable *rtp_dyn_payload,
- struct srtp_info *srtp_info)
+ struct srtp_info *srtp_info)
{
address null_addr;
conversation_t* p_conv;
@@ -887,6 +977,8 @@ srtp_add_address(packet_info *pinfo, address *addr, int port, int other_port,
p_conv_data->is_video = is_video;
p_conv_data->rtp_dyn_payload = rtp_dyn_payload;
p_conv_data->srtp_info = srtp_info;
+ p_conv_data->bta2dp_info = NULL;
+ p_conv_data->btvdp_info = NULL;
}
/* Set up an RTP conversation */
@@ -899,7 +991,7 @@ rtp_add_address(packet_info *pinfo, address *addr, int port, int other_port,
}
static gboolean
-dissect_rtp_heur_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gboolean check_destport)
+dissect_rtp_heur_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data, gboolean check_destport)
{
guint8 octet1;
unsigned int version;
@@ -954,20 +1046,20 @@ dissect_rtp_heur_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gbo
return FALSE;
}
- dissect_rtp( tvb, pinfo, tree );
+ dissect_rtp( tvb, pinfo, tree, data );
return TRUE;
}
static gboolean
-dissect_rtp_heur_udp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_ )
+dissect_rtp_heur_udp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data )
{
- return dissect_rtp_heur_common(tvb, pinfo, tree, TRUE);
+ return dissect_rtp_heur_common(tvb, pinfo, tree, data, TRUE);
}
static gboolean
-dissect_rtp_heur_stun( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_ )
+dissect_rtp_heur_stun( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data )
{
- return dissect_rtp_heur_common(tvb, pinfo, tree, FALSE);
+ return dissect_rtp_heur_common(tvb, pinfo, tree, data, FALSE);
}
/*
@@ -975,14 +1067,13 @@ dissect_rtp_heur_stun( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void
*/
static void
process_rtp_payload(tvbuff_t *newtvb, packet_info *pinfo, proto_tree *tree,
- proto_tree *rtp_tree,
- unsigned int payload_type)
+ proto_tree *rtp_tree, unsigned int payload_type)
{
struct _rtp_conversation_info *p_conv_data = NULL;
gboolean found_match = FALSE;
int payload_len;
struct srtp_info *srtp_info;
- int offset=0;
+ int offset = 0;
payload_len = tvb_length_remaining(newtvb, offset);
@@ -1015,10 +1106,9 @@ process_rtp_payload(tvbuff_t *newtvb, packet_info *pinfo, proto_tree *tree,
proto_tree_add_item(rtp_tree, hf_srtp_auth_tag, newtvb, offset, srtp_info->auth_tag_len, ENC_NA);
/*offset += srtp_info->auth_tag_len;*/
}
- }
-
- /* if the payload type is dynamic, we check if the conv is set and we look for the pt definition */
- else if ( (payload_type >= PT_UNDF_96 && payload_type <= PT_UNDF_127) ) {
+ } else if (p_conv_data && !p_conv_data->bta2dp_info && !p_conv_data->btvdp_info &&
+ payload_type >= PT_UNDF_96 && payload_type <= PT_UNDF_127) {
+ /* if the payload type is dynamic, we check if the conv is set and we look for the pt definition */
if (p_conv_data && p_conv_data->rtp_dyn_payload) {
gchar *payload_type_str = NULL;
encoding_name_and_rate_t *encoding_name_and_rate_pt = NULL;
@@ -1041,6 +1131,34 @@ process_rtp_payload(tvbuff_t *newtvb, packet_info *pinfo, proto_tree *tree,
}
}
+ } else if (p_conv_data && p_conv_data->bta2dp_info) {
+ tvbuff_t *nexttvb;
+ gint suboffset = 0;
+
+ found_match = TRUE;
+
+ if (p_conv_data->bta2dp_info->content_protection_type == BTAVDTP_CONTENT_PROTECTION_TYPE_SCMS_T) {
+ nexttvb = tvb_new_subset(newtvb, 0, 1, 1);
+ call_dissector(bta2dp_content_protection_header_scms_t, nexttvb, pinfo, tree);
+ suboffset = 1;
+ }
+
+ nexttvb = tvb_new_subset_remaining(newtvb, suboffset);
+ call_dissector(p_conv_data->bta2dp_info->codec_dissector, nexttvb, pinfo, tree);
+ } else if (p_conv_data && p_conv_data->btvdp_info) {
+ tvbuff_t *nexttvb;
+ gint suboffset = 0;
+
+ found_match = TRUE;
+
+ if (p_conv_data->btvdp_info->content_protection_type == BTAVDTP_CONTENT_PROTECTION_TYPE_SCMS_T) {
+ nexttvb = tvb_new_subset(newtvb, 0, 1, 1);
+ call_dissector(bta2dp_content_protection_header_scms_t, nexttvb, pinfo, tree);
+ suboffset = 1;
+ }
+
+ nexttvb = tvb_new_subset_remaining(newtvb, suboffset);
+ call_dissector(p_conv_data->btvdp_info->codec_dissector, nexttvb, pinfo, tree);
}
/* if we don't found, it is static OR could be set static from the preferences */
@@ -1265,7 +1383,7 @@ dissect_rtp_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
static void
dissect_rtp_rfc2198(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
- int offset = 0;
+ gint offset = 0;
guint8 octet1;
int cnt;
gboolean hdr_follow = TRUE;
@@ -1355,7 +1473,7 @@ dissect_rtp_rfc2198(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
static void
dissect_rtp_hext_rfc5215_onebyte( tvbuff_t *tvb, packet_info *pinfo,
- proto_tree *rtp_hext_tree )
+ proto_tree *rtp_hext_tree )
{
proto_item *ti = NULL;
proto_tree *rtp_hext_rfc5285_tree = NULL;
@@ -1409,7 +1527,7 @@ dissect_rtp_hext_rfc5215_onebyte( tvbuff_t *tvb, packet_info *pinfo,
static void
dissect_rtp_hext_rfc5215_twobytes(tvbuff_t *parent_tvb, guint id_offset,
- guint8 id, tvbuff_t *tvb, packet_info *pinfo, proto_tree *rtp_hext_tree)
+ guint8 id, tvbuff_t *tvb, packet_info *pinfo, proto_tree *rtp_hext_tree)
{
proto_item *ti = NULL;
proto_tree *rtp_hext_rfc5285_tree = NULL;
@@ -1454,8 +1572,8 @@ dissect_rtp_hext_rfc5215_twobytes(tvbuff_t *parent_tvb, guint id_offset,
}
}
-static void
-dissect_rtp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
+static gint
+dissect_rtp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
{
proto_item *ti = NULL;
proto_tree *volatile rtp_tree = NULL;
@@ -1485,8 +1603,8 @@ dissect_rtp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
/*struct srtp_info *srtp_info = NULL;*/
/*unsigned int srtp_offset;*/
unsigned int hdrext_offset = 0;
- tvbuff_t *newtvb = NULL;
-
+ tvbuff_t *newtvb = NULL;
+ const char *pt = NULL;
/* Can tap up to 4 RTP packets within same packet */
static struct _rtp_info rtp_info_arr[4];
static int rtp_info_current=0;
@@ -1506,24 +1624,24 @@ dissect_rtp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
switch (global_rtp_version0_type) {
case RTP0_STUN:
call_dissector(stun_handle, tvb, pinfo, tree);
- return;
+ return tvb_length(tvb);
case RTP0_CLASSICSTUN:
call_dissector(classicstun_handle, tvb, pinfo, tree);
- return;
+ return tvb_length(tvb);
case RTP0_T38:
call_dissector(t38_handle, tvb, pinfo, tree);
- return;
+ return tvb_length(tvb);
case RTP0_SPRT:
call_dissector(sprt_handle, tvb, pinfo, tree);
- return;
+ return tvb_length(tvb);
case RTP0_INVALID:
if (!(tvb_memeql(tvb, 4, "ZRTP", 4)))
{
call_dissector(zrtp_handle,tvb,pinfo,tree);
- return;
+ return tvb_length(tvb);
}
default:
; /* Unknown or unsupported version (let it fall through) */
@@ -1548,7 +1666,7 @@ dissect_rtp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
proto_tree_add_uint( rtp_tree, hf_rtp_version, tvb,
offset, 1, octet1);
}
- return;
+ return offset;
}
padding_set = RTP_PADDING( octet1 );
@@ -1636,6 +1754,12 @@ dissect_rtp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
}
#endif
+ if (p_conv_data && p_conv_data->bta2dp_info && p_conv_data->bta2dp_info->codec_dissector) {
+ rtp_info->info_payload_type_str = (const char *) dissector_handle_get_short_name(p_conv_data->bta2dp_info->codec_dissector);
+ } else if (p_conv_data && p_conv_data->btvdp_info && p_conv_data->btvdp_info->codec_dissector) {
+ rtp_info->info_payload_type_str = (const char *) dissector_handle_get_short_name(p_conv_data->btvdp_info->codec_dissector);
+ }
+
/* if it is dynamic payload, let use the conv data to see if it is defined */
if ( (payload_type>95) && (payload_type<128) ) {
if (p_conv_data && p_conv_data->rtp_dyn_payload){
@@ -1648,15 +1772,22 @@ dissect_rtp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
}
}
+ if (p_conv_data && p_conv_data->bta2dp_info) {
+ pt = (p_conv_data->bta2dp_info->codec_dissector) ? dissector_handle_get_short_name(p_conv_data->bta2dp_info->codec_dissector) : "Unknown";
+ } else if (p_conv_data && p_conv_data->btvdp_info) {
+ pt = (p_conv_data->btvdp_info->codec_dissector) ? dissector_handle_get_short_name(p_conv_data->btvdp_info->codec_dissector) : "Unknown";
+ } else {
+ pt = (payload_type_str ? payload_type_str : val_to_str_ext(payload_type, &rtp_payload_type_vals_ext,"Unknown (%u)"));
+ }
+
col_add_fstr( pinfo->cinfo, COL_INFO,
"PT=%s, SSRC=0x%X, Seq=%u, Time=%u%s",
- payload_type_str ? payload_type_str : val_to_str_ext( payload_type, &rtp_payload_type_vals_ext,"Unknown (%u)" ),
+ pt,
sync_src,
seq_num,
timestamp,
marker_set ? ", Mark" : "");
-
if ( tree ) {
proto_tree *item;
/* Create RTP protocol tree */
@@ -1682,10 +1813,8 @@ dissect_rtp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
proto_tree_add_boolean( rtp_tree, hf_rtp_marker, tvb, offset,
1, octet2 );
- proto_tree_add_uint_format_value( rtp_tree, hf_rtp_payload_type, tvb,
- offset, 1, octet2, "%s (%u)",
- payload_type_str ? payload_type_str : val_to_str_ext_const( payload_type, &rtp_payload_type_vals_ext,"Unknown"),
- payload_type);
+ proto_tree_add_uint_format( rtp_tree, hf_rtp_payload_type, tvb,
+ offset, 1, octet2, "Payload type: %s (%u)", pt, payload_type);
offset++;
@@ -1714,7 +1843,7 @@ dissect_rtp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
proto_item_append_text(ti, " (%u items)", csrc_count);
rtp_csrc_tree = proto_item_add_subtree( ti, ett_csrc_list );
- for (i = 0; i < csrc_count; i++ ) {
+ for (i = 0; i < csrc_count; i++ ) {
csrc_item = tvb_get_ntohl( tvb, offset );
proto_tree_add_uint_format( rtp_csrc_tree,
hf_rtp_csrc_item, tvb, offset, 4,
@@ -1788,7 +1917,7 @@ dissect_rtp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
call_dissector(data_handle,
tvb_new_subset_remaining(tvb, offset),
pinfo, rtp_tree);
- return;
+ return tvb_length(tvb);;
}
padding_count = tvb_get_guint8( tvb,
@@ -1800,6 +1929,24 @@ dissect_rtp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
rtp_info->info_payload_len = tvb_length_remaining(tvb, offset);
rtp_info->info_padding_count = padding_count;
+ if (p_conv_data && p_conv_data->bta2dp_info) {
+ if (p_conv_data->bta2dp_info->codec_dissector == sbc_handle) {
+ rtp_info->info_payload_offset += 1;
+ rtp_info->info_payload_len -= 1;
+ }
+
+ if (p_conv_data->bta2dp_info->content_protection_type == BTAVDTP_CONTENT_PROTECTION_TYPE_SCMS_T) {
+ rtp_info->info_payload_offset += 1;
+ rtp_info->info_payload_len -= 1;
+ }
+ }
+
+ if (p_conv_data && p_conv_data->btvdp_info &&
+ p_conv_data->bta2dp_info->content_protection_type == BTAVDTP_CONTENT_PROTECTION_TYPE_SCMS_T) {
+ rtp_info->info_payload_offset += 1;
+ rtp_info->info_payload_len -= 1;
+ }
+
if (data_len > 0) {
/*
* There's data left over when you take out
@@ -1811,7 +1958,7 @@ dissect_rtp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
offset,
data_len,
data_len,
- payload_type );
+ payload_type);
} CATCH_ALL {
if (!pinfo->flags.in_error_pkt)
tap_queue_packet(rtp_tap, pinfo, rtp_info);
@@ -1852,13 +1999,34 @@ dissect_rtp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
/*
* No padding.
*/
+ rtp_info->info_payload_offset = offset;
+ rtp_info->info_payload_len = tvb_length_remaining(tvb, offset);
+
+ if (p_conv_data && p_conv_data->bta2dp_info) {
+ if (p_conv_data->bta2dp_info->codec_dissector == sbc_handle) {
+ rtp_info->info_payload_offset += 1;
+ rtp_info->info_payload_len -= 1;
+ }
+
+ if (p_conv_data->bta2dp_info->content_protection_type == BTAVDTP_CONTENT_PROTECTION_TYPE_SCMS_T) {
+ rtp_info->info_payload_offset += 1;
+ rtp_info->info_payload_len -= 1;
+ }
+ }
+
+ if (p_conv_data && p_conv_data->btvdp_info &&
+ p_conv_data->bta2dp_info->content_protection_type == BTAVDTP_CONTENT_PROTECTION_TYPE_SCMS_T) {
+ rtp_info->info_payload_offset += 1;
+ rtp_info->info_payload_len -= 1;
+ }
+
if (tvb_reported_length_remaining(tvb, offset) > 0) {
/* Ensure that tap is called after packet dissection, even in case of exception */
TRY {
dissect_rtp_data( tvb, pinfo, tree, rtp_tree, offset,
tvb_length_remaining( tvb, offset ),
tvb_reported_length_remaining( tvb, offset ),
- payload_type );
+ payload_type);
} CATCH_ALL {
if (!pinfo->flags.in_error_pkt)
tap_queue_packet(rtp_tap, pinfo, rtp_info);
@@ -1866,11 +2034,11 @@ dissect_rtp( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
}
ENDTRY;
}
- rtp_info->info_payload_offset = offset;
- rtp_info->info_payload_len = tvb_length_remaining(tvb, offset);
}
if (!pinfo->flags.in_error_pkt)
tap_queue_packet(rtp_tap, pinfo, rtp_info);
+
+ return offset;
}
static void
@@ -2079,6 +2247,8 @@ get_conv_info(packet_info *pinfo, struct _rtp_info *rtp_info)
p_conv_packet_data->rtp_dyn_payload = p_conv_data->rtp_dyn_payload;
p_conv_packet_data->rtp_conv_info = p_conv_data->rtp_conv_info;
p_conv_packet_data->srtp_info = p_conv_data->srtp_info;
+ p_conv_packet_data->bta2dp_info = p_conv_data->bta2dp_info;
+ p_conv_packet_data->btvdp_info = p_conv_data->btvdp_info;
p_add_proto_data(pinfo->fd, proto_rtp, 0, p_conv_packet_data);
/* calculate extended sequence number */
@@ -2129,8 +2299,8 @@ show_setup_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
/* Dissect PacketCable CCC header */
-static void
-dissect_pkt_ccc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+static int
+dissect_pkt_ccc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
{
proto_item *ti = NULL;
proto_tree *pkt_ccc_tree = NULL;
@@ -2144,7 +2314,7 @@ dissect_pkt_ccc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
ENC_TIME_NTP|ENC_BIG_ENDIAN);
}
- dissect_rtp(tvb, pinfo, tree);
+ return dissect_rtp(tvb, pinfo, tree, data);
}
@@ -2194,7 +2364,7 @@ proto_register_pkt_ccc(void)
proto_register_field_array(proto_pkt_ccc, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
- register_dissector("pkt_ccc", dissect_pkt_ccc, proto_pkt_ccc);
+ new_register_dissector("pkt_ccc", dissect_pkt_ccc, proto_pkt_ccc);
pkt_ccc_module = prefs_register_protocol(proto_pkt_ccc, proto_reg_handoff_pkt_ccc);
@@ -3041,7 +3211,7 @@ proto_register_rtp(void)
proto_register_field_array(proto_rtp, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
- register_dissector("rtp", dissect_rtp, proto_rtp);
+ new_register_dissector("rtp", dissect_rtp, proto_rtp);
register_dissector("rtp.rfc2198", dissect_rtp_rfc2198, proto_rtp);
rtp_tap = register_tap("rtp");
@@ -3128,8 +3298,16 @@ proto_reg_handoff_rtp(void)
sprt_handle = find_dissector("sprt");
v150fw_handle = find_dissector("v150fw");
+ bta2dp_content_protection_header_scms_t = find_dissector("bta2dp_content_protection_header_scms_t");
+ btvdp_content_protection_header_scms_t = find_dissector("btvdp_content_protection_header_scms_t");
+ bta2dp_handle = find_dissector("bta2dp");
+ btvdp_handle = find_dissector("btvdp");
+ sbc_handle = find_dissector("sbc");
+
dissector_add_string("rtp_dyn_payload_type", "v150fw", v150fw_handle);
+ dissector_add_handle("btl2cap.cid", rtp_handle);
+
rtp_prefs_initialized = TRUE;
} else {
dissector_delete_uint("rtp.pt", rtp_saved_rfc2198_pt, rtp_rfc2198_handle);
diff --git a/epan/dissectors/packet-rtp.h b/epan/dissectors/packet-rtp.h
index ec95019dd9..7fb7b69c8a 100644
--- a/epan/dissectors/packet-rtp.h
+++ b/epan/dissectors/packet-rtp.h
@@ -27,13 +27,16 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
+#include "epan/packet.h"
#include "ws_symbol_export.h"
+#include "packet-btavdtp.h"
+
struct _rtp_info {
unsigned int info_version;
gboolean info_padding_set;
gboolean info_marker_set;
- gboolean info_is_video;
+ gboolean info_is_video;
unsigned int info_payload_type;
unsigned int info_padding_count;
guint16 info_seq_num;
@@ -44,10 +47,10 @@ struct _rtp_info {
guint info_payload_offset; /* start of payload relative to info_data */
guint info_payload_len; /* length of payload (incl padding) */
gboolean info_is_srtp;
- guint32 info_setup_frame_num; /* the frame num of the packet that set this RTP connection */
+ guint32 info_setup_frame_num; /* the frame num of the packet that set this RTP connection */
const guint8* info_data; /* pointer to raw rtp data */
- gchar *info_payload_type_str;
- gint info_payload_rate;
+ const gchar *info_payload_type_str;
+ gint info_payload_rate;
/*
* info_data: pointer to raw rtp data = header + payload incl. padding.
* That should be safe because the "epan_dissect_t" constructed for the packet
@@ -116,6 +119,8 @@ struct _rtp_conversation_info
* to the rtp dissector
*/
struct srtp_info *srtp_info; /* SRTP context */
+ bta2dp_codec_info_t *bta2dp_info;
+ btvdp_codec_info_t *btvdp_info;
};
typedef struct {
@@ -144,6 +149,12 @@ void srtp_add_address(packet_info *pinfo,
GHashTable *rtp_dyn_payload,
struct srtp_info *srtp_info);
+/* Add an Bluetooth conversation with the given details */
+void
+bluetooth_add_address(packet_info *pinfo, address *addr,
+ const gchar *setup_method, guint32 setup_frame_number,
+ gboolean is_video, void *data);
+
/* Free and destroy the dyn_payload hash table */
WS_DLL_PUBLIC
void rtp_free_hash_dyn_payload(GHashTable *rtp_dyn_payload);
diff --git a/ui/rtp_stream.h b/ui/rtp_stream.h
index 059444b96d..14c484bbd9 100644
--- a/ui/rtp_stream.h
+++ b/ui/rtp_stream.h
@@ -58,7 +58,7 @@ typedef struct _rtp_stream_info {
guint32 dest_port;
guint32 ssrc;
guint8 pt;
- gchar *info_payload_type_str;
+ const gchar *info_payload_type_str;
guint32 npackets;
guint32 first_frame_num; /**< frame number of first frame */
diff --git a/ui/tap-rtp-common.c b/ui/tap-rtp-common.c
index 6785e5fd1d..9f9c070f6c 100644
--- a/ui/tap-rtp-common.c
+++ b/ui/tap-rtp-common.c
@@ -417,7 +417,7 @@ static const mimetype_and_clock mimetype_and_clock_map[] = {
#define NUM_DYN_CLOCK_VALUES (sizeof mimetype_and_clock_map / sizeof mimetype_and_clock_map[0])
static guint32
-get_dyn_pt_clock_rate(gchar *payload_type_str)
+get_dyn_pt_clock_rate(const gchar *payload_type_str)
{
int i;