Bluetooth: Make dissectors independent of passed data

If Bluetooth dissectors has additional data from previous layer - good.
But if do not... try to decode as much as possible - probably using
some "force" dissector preferences you can decode payload correctly.

Change-Id: I6427afafb987ed3b9b751fd91616e670802b3542
Reviewed-on: https://code.wireshark.org/review/11021
Reviewed-by: Michal Labedzki <michal.labedzki@tieto.com>
This commit is contained in:
Michal Labedzki 2015-09-27 18:22:32 +02:00
parent 106c289369
commit bdf3c0b558
10 changed files with 586 additions and 765 deletions

View File

@ -39,7 +39,7 @@
#define PACKET_TYPE_CONTINUE 0x02
#define PACKET_TYPE_END 0x03
static int proto_btavctp = -1;
int proto_btavctp = -1;
static int hf_btavctp_transaction = -1;
static int hf_btavctp_packet_type = -1;
@ -107,7 +107,6 @@ dissect_btavctp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
proto_item *pitem;
proto_item *ipid_item = NULL;
btavctp_data_t *avctp_data;
btl2cap_data_t *l2cap_data;
tvbuff_t *next_tvb;
gint offset = 0;
guint packet_type;
@ -118,11 +117,28 @@ dissect_btavctp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
guint length;
guint i_frame;
gboolean ipid = FALSE;
guint32 interface_id;
guint32 adapter_id;
guint32 chandle;
guint32 psm;
gint previous_proto;
/* Reject the packet if data is NULL */
if (data == NULL)
return 0;
l2cap_data = (btl2cap_data_t *) data;
previous_proto = (GPOINTER_TO_INT(wmem_list_frame_data(wmem_list_frame_prev(wmem_list_tail(pinfo->layers)))));
if (previous_proto == proto_btl2cap) {
btl2cap_data_t *l2cap_data;
l2cap_data = (btl2cap_data_t *) data;
interface_id = l2cap_data->interface_id;
adapter_id = l2cap_data->adapter_id;
chandle = l2cap_data->chandle;
psm = l2cap_data->psm;
} else {
interface_id = HCI_INTERFACE_DEFAULT;
adapter_id = HCI_ADAPTER_DEFAULT;
chandle = 0;
psm = 0;
}
ti = proto_tree_add_item(tree, proto_btavctp, tvb, offset, tvb_captured_length_remaining(tvb, offset), ENC_NA);
btavctp_tree = proto_item_add_subtree(ti, ett_btavctp);
@ -196,10 +212,10 @@ dissect_btavctp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
avctp_data = wmem_new(wmem_packet_scope(), btavctp_data_t);
avctp_data->cr = cr;
avctp_data->interface_id = l2cap_data->interface_id;
avctp_data->adapter_id = l2cap_data->adapter_id;
avctp_data->chandle = l2cap_data->chandle;
avctp_data->psm = l2cap_data->psm;
avctp_data->interface_id = interface_id;
avctp_data->adapter_id = adapter_id;
avctp_data->chandle = chandle;
avctp_data->psm = psm;
length = tvb_reported_length_remaining(tvb, offset);
@ -220,37 +236,20 @@ dissect_btavctp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
} else {
fragment_t *fragment;
wmem_tree_key_t key[6];
guint32 k_interface_id;
guint32 k_adapter_id;
guint32 k_chandle;
guint32 k_psm;
guint32 k_frame_number;
guint32 interface_id;
guint32 adapter_id;
guint32 chandle;
guint32 psm;
guint32 frame_number;
interface_id = l2cap_data->interface_id;
adapter_id = l2cap_data->adapter_id;
chandle = l2cap_data->chandle;
psm = l2cap_data->psm;
k_interface_id = interface_id;
k_adapter_id = adapter_id;
k_chandle = chandle;
k_psm = psm;
k_frame_number = pinfo->fd->num;
frame_number = pinfo->fd->num;
key[0].length = 1;
key[0].key = &k_interface_id;
key[0].key = &interface_id;
key[1].length = 1;
key[1].key = &k_adapter_id;
key[1].key = &adapter_id;
key[2].length = 1;
key[2].key = &k_chandle;
key[2].key = &chandle;
key[3].length = 1;
key[3].key = &k_psm;
key[3].key = &psm;
key[4].length = 1;
key[4].key = &k_frame_number;
key[4].key = &frame_number;
key[5].length = 0;
key[5].key = NULL;
@ -309,22 +308,18 @@ dissect_btavctp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
fragments->chandle = chandle;
fragments->psm = psm;
k_interface_id = interface_id;
k_adapter_id = adapter_id;
k_chandle = chandle;
k_psm = psm;
k_frame_number = pinfo->fd->num;
frame_number = pinfo->fd->num;
key[0].length = 1;
key[0].key = &k_interface_id;
key[0].key = &interface_id;
key[1].length = 1;
key[1].key = &k_adapter_id;
key[1].key = &adapter_id;
key[2].length = 1;
key[2].key = &k_chandle;
key[2].key = &chandle;
key[3].length = 1;
key[3].key = &k_psm;
key[3].key = &psm;
key[4].length = 1;
key[4].key = &k_frame_number;
key[4].key = &frame_number;
key[5].length = 0;
key[5].key = NULL;
@ -357,22 +352,18 @@ dissect_btavctp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
fragments->chandle = chandle;
fragments->psm = psm;
k_interface_id = interface_id;
k_adapter_id = adapter_id;
k_chandle = chandle;
k_psm = psm;
k_frame_number = pinfo->fd->num;
frame_number = pinfo->fd->num;
key[0].length = 1;
key[0].key = &k_interface_id;
key[0].key = &interface_id;
key[1].length = 1;
key[1].key = &k_adapter_id;
key[1].key = &adapter_id;
key[2].length = 1;
key[2].key = &k_chandle;
key[2].key = &chandle;
key[3].length = 1;
key[3].key = &k_psm;
key[3].key = &psm;
key[4].length = 1;
key[4].key = &k_frame_number;
key[4].key = &frame_number;
key[5].length = 0;
key[5].key = NULL;

View File

@ -33,6 +33,8 @@ typedef struct _btavctp_data_t {
guint8 cr;
} btavctp_data_t;
extern int proto_btavctp;
#endif
/*

View File

@ -275,6 +275,13 @@ static wmem_tree_t *reassembling = NULL;
static wmem_tree_t *timing = NULL;
wmem_tree_t *btavrcp_song_positions = NULL;
typedef struct _avrcp_proto_data_t {
guint32 interface_id;
guint32 adapter_id;
guint32 chandle;
guint32 channel;
} avrcp_proto_data_t;
typedef struct _fragment {
guint start_frame_number;
guint end_frame_number;
@ -999,7 +1006,7 @@ dissect_subunit(tvbuff_t *tvb, proto_tree *tree, gint offset, gboolean is_comman
static gint
dissect_vendor_dependant(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
gint offset, guint ctype, guint32 *op, guint32 *op_arg,
gboolean is_command, btavctp_data_t *avctp_data)
gboolean is_command, avrcp_proto_data_t *avrcp_proto_data)
{
proto_item *pitem;
guint pdu_id;
@ -1009,16 +1016,8 @@ dissect_vendor_dependant(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
guint parameter_length;
gint length;
wmem_tree_key_t key[7];
guint32 k_interface_id;
guint32 k_adapter_id;
guint32 k_chandle;
guint32 k_psm;
guint32 k_op;
guint32 k_frame_number;
guint32 interface_id;
guint32 adapter_id;
guint32 chandle;
guint32 psm;
guint32 frame_number;
guint volume;
guint volume_percent;
fragment_t *fragment;
@ -1026,11 +1025,6 @@ dissect_vendor_dependant(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
*op_arg = 0;
interface_id = avctp_data->interface_id;
adapter_id = avctp_data->adapter_id;
chandle = avctp_data->chandle;
psm = avctp_data->psm;
proto_tree_add_item(tree, hf_btavrcp_company_id, tvb, offset, 3, ENC_BIG_ENDIAN);
company_id = tvb_get_ntoh24(tvb, offset);
offset += 3;
@ -1075,12 +1069,8 @@ dissect_vendor_dependant(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
length = tvb_reported_length_remaining(tvb, offset);
if (packet_type == PACKET_TYPE_START) {
if (pinfo->fd->flags.visited == 0 && tvb_captured_length_remaining(tvb, offset) == length) {
k_interface_id = interface_id;
k_adapter_id = adapter_id;
k_chandle = chandle;
k_psm = psm;
k_op = pdu_id | (company_id << 8);
k_frame_number = pinfo->fd->num;
frame_number = pinfo->fd->num;
fragment = wmem_new(wmem_file_scope(), fragment_t);
fragment->start_frame_number = pinfo->fd->num;
@ -1098,24 +1088,24 @@ dissect_vendor_dependant(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
wmem_tree_insert32(fragment->fragments, fragment->count, data_fragment);
key[0].length = 1;
key[0].key = &k_interface_id;
key[0].key = &avrcp_proto_data->interface_id;
key[1].length = 1;
key[1].key = &k_adapter_id;
key[1].key = &avrcp_proto_data->adapter_id;
key[2].length = 1;
key[2].key = &k_chandle;
key[2].key = &avrcp_proto_data->chandle;
key[3].length = 1;
key[3].key = &k_psm;
key[3].key = &avrcp_proto_data->channel;
key[4].length = 1;
key[4].key = &k_op;
key[5].length = 1;
key[5].key = &k_frame_number;
key[5].key = &frame_number;
key[6].length = 0;
key[6].key = NULL;
fragment->interface_id = interface_id;
fragment->adapter_id = adapter_id;
fragment->chandle = chandle;
fragment->psm = psm;
fragment->interface_id = avrcp_proto_data->interface_id;
fragment->adapter_id = avrcp_proto_data->adapter_id;
fragment->chandle = avrcp_proto_data->chandle;
fragment->psm = avrcp_proto_data->channel;
fragment->op = pdu_id | (company_id << 8);
wmem_tree_insert32_array(reassembling, key, fragment);
@ -1125,33 +1115,29 @@ dissect_vendor_dependant(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
return offset;
} else if (packet_type == PACKET_TYPE_CONTINUE) {
if (pinfo->fd->flags.visited == 0 && tvb_captured_length_remaining(tvb, offset) == length) {
k_interface_id = interface_id;
k_adapter_id = adapter_id;
k_chandle = chandle;
k_psm = psm;
k_op = pdu_id | (company_id << 8);
k_frame_number = pinfo->fd->num;
frame_number = pinfo->fd->num;
key[0].length = 1;
key[0].key = &k_interface_id;
key[0].key = &avrcp_proto_data->interface_id;
key[1].length = 1;
key[1].key = &k_adapter_id;
key[1].key = &avrcp_proto_data->adapter_id;
key[2].length = 1;
key[2].key = &k_chandle;
key[2].key = &avrcp_proto_data->chandle;
key[3].length = 1;
key[3].key = &k_psm;
key[3].key = &avrcp_proto_data->channel;
key[4].length = 1;
key[4].key = &k_op;
key[5].length = 1;
key[5].key = &k_frame_number;
key[5].key = &frame_number;
key[6].length = 0;
key[6].key = NULL;
fragment = (fragment_t *)wmem_tree_lookup32_array_le(reassembling, key);
if (fragment && fragment->interface_id == interface_id &&
fragment->adapter_id == adapter_id &&
fragment->chandle == chandle &&
fragment->psm == psm &&
if (fragment && fragment->interface_id == avrcp_proto_data->interface_id &&
fragment->adapter_id == avrcp_proto_data->adapter_id &&
fragment->chandle == avrcp_proto_data->chandle &&
fragment->psm == avrcp_proto_data->channel &&
fragment->op == (pdu_id | (company_id << 8)) &&
fragment->state == 1) {
fragment->count += 1;
@ -1173,33 +1159,29 @@ dissect_vendor_dependant(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
col_append_str(pinfo->cinfo, COL_INFO, " [end]");
k_interface_id = interface_id;
k_adapter_id = adapter_id;
k_chandle = chandle;
k_psm = psm;
k_op = pdu_id | (company_id << 8);
k_frame_number = pinfo->fd->num;
frame_number = pinfo->fd->num;
key[0].length = 1;
key[0].key = &k_interface_id;
key[0].key = &avrcp_proto_data->interface_id;
key[1].length = 1;
key[1].key = &k_adapter_id;
key[1].key = &avrcp_proto_data->adapter_id;
key[2].length = 1;
key[2].key = &k_chandle;
key[2].key = &avrcp_proto_data->chandle;
key[3].length = 1;
key[3].key = &k_psm;
key[3].key = &avrcp_proto_data->channel;
key[4].length = 1;
key[4].key = &k_op;
key[5].length = 1;
key[5].key = &k_frame_number;
key[5].key = &frame_number;
key[6].length = 0;
key[6].key = NULL;
fragment = (fragment_t *)wmem_tree_lookup32_array_le(reassembling, key);
if (fragment && fragment->interface_id == interface_id &&
fragment->adapter_id == adapter_id &&
fragment->chandle == chandle &&
fragment->psm == psm &&
if (fragment && fragment->interface_id == avrcp_proto_data->interface_id &&
fragment->adapter_id == avrcp_proto_data->adapter_id &&
fragment->chandle == avrcp_proto_data->chandle &&
fragment->psm == avrcp_proto_data->channel &&
fragment->op == (pdu_id | (company_id << 8))) {
@ -1595,16 +1577,14 @@ dissect_vendor_dependant(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
} 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;
frame_number = pinfo->fd->num;
key[0].length = 1;
key[0].key = &k_interface_id;
key[0].key = &avrcp_proto_data->interface_id;
key[1].length = 1;
key[1].key = &k_adapter_id;
key[1].key = &avrcp_proto_data->adapter_id;
key[2].length = 1;
key[2].key = &k_frame_number;
key[2].key = &frame_number;
key[3].length = 0;
key[3].key = NULL;
@ -1690,33 +1670,29 @@ dissect_vendor_dependant(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
offset += 1;
if (pinfo->fd->flags.visited == 0) {
k_interface_id = interface_id;
k_adapter_id = adapter_id;
k_chandle = chandle;
k_psm = psm;
k_op = continuing_op;
k_frame_number = pinfo->fd->num;
frame_number = pinfo->fd->num;
key[0].length = 1;
key[0].key = &k_interface_id;
key[0].key = &avrcp_proto_data->interface_id;
key[1].length = 1;
key[1].key = &k_adapter_id;
key[1].key = &avrcp_proto_data->adapter_id;
key[2].length = 1;
key[2].key = &k_chandle;
key[2].key = &avrcp_proto_data->chandle;
key[3].length = 1;
key[3].key = &k_psm;
key[3].key = &avrcp_proto_data->channel;
key[4].length = 1;
key[4].key = &k_op;
key[5].length = 1;
key[5].key = &k_frame_number;
key[5].key = &frame_number;
key[6].length = 0;
key[6].key = NULL;
fragment = (fragment_t *)wmem_tree_lookup32_array_le(reassembling, key);
if (fragment && fragment->interface_id == interface_id &&
fragment->adapter_id == adapter_id &&
fragment->chandle == chandle &&
fragment->psm == psm &&
if (fragment && fragment->interface_id == avrcp_proto_data->interface_id &&
fragment->adapter_id == avrcp_proto_data->adapter_id &&
fragment->chandle == avrcp_proto_data->chandle &&
fragment->psm == avrcp_proto_data->channel &&
fragment->op == continuing_op &&
fragment->state == 0) {
fragment->state = 1;
@ -1739,33 +1715,29 @@ dissect_vendor_dependant(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
offset += 1;
if (pinfo->fd->flags.visited == 0) {
k_interface_id = interface_id;
k_adapter_id = adapter_id;
k_chandle = chandle;
k_psm = psm;
k_op = continuing_op;
k_frame_number = pinfo->fd->num;
frame_number = pinfo->fd->num;
key[0].length = 1;
key[0].key = &k_interface_id;
key[0].key = &avrcp_proto_data->interface_id;
key[1].length = 1;
key[1].key = &k_adapter_id;
key[1].key = &avrcp_proto_data->adapter_id;
key[2].length = 1;
key[2].key = &k_chandle;
key[2].key = &avrcp_proto_data->chandle;
key[3].length = 1;
key[3].key = &k_psm;
key[3].key = &avrcp_proto_data->channel;
key[4].length = 1;
key[4].key = &k_op;
key[5].length = 1;
key[5].key = &k_frame_number;
key[5].key = &frame_number;
key[6].length = 0;
key[6].key = NULL;
fragment = (fragment_t *)wmem_tree_lookup32_array_le(reassembling, key);
if (fragment && fragment->interface_id == interface_id &&
fragment->adapter_id == adapter_id &&
fragment->chandle == chandle &&
fragment->psm == psm &&
if (fragment && fragment->interface_id == avrcp_proto_data->interface_id &&
fragment->adapter_id == avrcp_proto_data->adapter_id &&
fragment->chandle == avrcp_proto_data->chandle &&
fragment->psm == avrcp_proto_data->channel &&
fragment->op == continuing_op &&
fragment->state == 0) {
fragment->state = 3;
@ -2105,24 +2077,32 @@ dissect_btavrcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
guint is_command;
timing_info_t *timing_info;
wmem_tree_key_t key[9];
guint32 k_interface_id;
guint32 k_adapter_id;
guint32 k_chandle;
guint32 k_psm;
guint32 k_opcode;
guint32 k_op;
guint32 k_op_arg;
guint32 k_frame_number;
guint32 interface_id;
guint32 adapter_id;
guint32 chandle;
guint32 psm;
btavctp_data_t *avctp_data;
guint32 frame_number;
gint previous_proto;
avrcp_proto_data_t avrcp_proto_data;
/* Reject the packet if data is NULL */
if (data == NULL)
return 0;
avctp_data = (btavctp_data_t *) data;
previous_proto = (GPOINTER_TO_INT(wmem_list_frame_data(wmem_list_frame_prev(wmem_list_tail(pinfo->layers)))));
if (previous_proto == proto_btavctp) {
btavctp_data_t *avctp_data;
avctp_data = (btavctp_data_t *) data;
avrcp_proto_data.interface_id = avctp_data->interface_id;
avrcp_proto_data.adapter_id = avctp_data->adapter_id;
avrcp_proto_data.chandle = avctp_data->chandle;
avrcp_proto_data.channel = avctp_data->psm;
is_command = !avctp_data->cr;
} else {
avrcp_proto_data.interface_id = HCI_INTERFACE_DEFAULT;
avrcp_proto_data.adapter_id = HCI_ADAPTER_DEFAULT;
avrcp_proto_data.chandle = 0;
avrcp_proto_data.channel = 0;
/* NOTE: There is need to allow user specify that */
is_command = (pinfo->p2p_dir == P2P_DIR_SENT);
}
ti = proto_tree_add_item(tree, proto_btavrcp, tvb, offset, tvb_captured_length_remaining(tvb, offset), ENC_NA);
btavrcp_tree = proto_item_add_subtree(ti, ett_btavrcp);
@ -2141,14 +2121,7 @@ dissect_btavrcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
break;
}
is_command = !avctp_data->cr;
interface_id = avctp_data->interface_id;
adapter_id = avctp_data->adapter_id;
chandle = avctp_data->chandle;
psm = avctp_data->psm;
if (avctp_data->psm == BTL2CAP_PSM_AVCTP_BRWS) {
if (avrcp_proto_data.channel == BTL2CAP_PSM_AVCTP_BRWS) {
col_append_str(pinfo->cinfo, COL_INFO, "Browsing");
offset = dissect_browsing(tvb, pinfo, btavrcp_tree, offset, is_command);
} else {
@ -2180,35 +2153,29 @@ dissect_btavrcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
break;
case OPCODE_VENDOR_DEPENDANT:
offset = dissect_vendor_dependant(tvb, pinfo, btavrcp_tree,
offset, ctype, &op, &op_arg, is_command, avctp_data);
offset, ctype, &op, &op_arg, is_command, &avrcp_proto_data);
break;
};
k_interface_id = interface_id;
k_adapter_id = adapter_id;
k_chandle = chandle;
k_psm = psm;
k_opcode = opcode;
k_op = op;
k_op_arg = (ctype == 0x0a) ? G_MAXUINT32 : op_arg;
k_frame_number = pinfo->fd->num;
frame_number = pinfo->fd->num;
key[0].length = 1;
key[0].key = &k_interface_id;
key[0].key = &avrcp_proto_data.interface_id;
key[1].length = 1;
key[1].key = &k_adapter_id;
key[1].key = &avrcp_proto_data.adapter_id;
key[2].length = 1;
key[2].key = &k_chandle;
key[2].key = &avrcp_proto_data.chandle;
key[3].length = 1;
key[3].key = &k_psm;
key[3].key = &avrcp_proto_data.channel;
key[4].length = 1;
key[4].key = &k_opcode;
key[4].key = &opcode;
key[5].length = 1;
key[5].key = &k_op;
key[5].key = &op;
key[6].length = 1;
key[6].key = &k_op_arg;
key[7].length = 1;
key[7].key = &k_frame_number;
key[7].key = &frame_number;
key[8].length = 0;
key[8].key = NULL;
@ -2231,10 +2198,10 @@ dissect_btavrcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
timing_info->response_timestamp.nsecs = 0;
timing_info->max_response_time = max_response_time;
timing_info->interface_id = interface_id;
timing_info->adapter_id = adapter_id;
timing_info->chandle = chandle;
timing_info->psm = psm;
timing_info->interface_id = avrcp_proto_data.interface_id;
timing_info->adapter_id = avrcp_proto_data.adapter_id;
timing_info->chandle = avrcp_proto_data.chandle;
timing_info->psm = avrcp_proto_data.channel;
timing_info->opcode = opcode;
timing_info->op = op;
timing_info->op_arg = op_arg;
@ -2243,10 +2210,10 @@ dissect_btavrcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
wmem_tree_insert32_array(timing, key, timing_info);
} else {
timing_info = (timing_info_t *)wmem_tree_lookup32_array_le(timing, key);
if (timing_info && timing_info->interface_id == interface_id &&
timing_info->adapter_id == adapter_id &&
timing_info->chandle == chandle &&
timing_info->psm == psm &&
if (timing_info && timing_info->interface_id == avrcp_proto_data.interface_id &&
timing_info->adapter_id == avrcp_proto_data.adapter_id &&
timing_info->chandle == avrcp_proto_data.chandle &&
timing_info->psm == avrcp_proto_data.channel &&
timing_info->opcode == opcode &&
timing_info->op == op &&
((ctype == 0x0a) ? 1 : (timing_info->op_arg == op_arg)) &&
@ -2257,41 +2224,35 @@ dissect_btavrcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
}
}
k_interface_id = interface_id;
k_adapter_id = adapter_id;
k_chandle = chandle;
k_psm = psm;
k_opcode = opcode;
k_op = op;
k_op_arg = (ctype == 0x0a) ? G_MAXUINT32 : op_arg;
k_frame_number = pinfo->fd->num;
frame_number = pinfo->fd->num;
key[0].length = 1;
key[0].key = &k_interface_id;
key[0].key = &avrcp_proto_data.interface_id;
key[1].length = 1;
key[1].key = &k_adapter_id;
key[1].key = &avrcp_proto_data.adapter_id;
key[2].length = 1;
key[2].key = &k_chandle;
key[2].key = &avrcp_proto_data.chandle;
key[3].length = 1;
key[3].key = &k_psm;
key[3].key = &avrcp_proto_data.channel;
key[4].length = 1;
key[4].key = &k_opcode;
key[4].key = &opcode;
key[5].length = 1;
key[5].key = &k_op;
key[5].key = &op;
key[6].length = 1;
key[6].key = &k_op_arg;
key[7].length = 1;
key[7].key = &k_frame_number;
key[7].key = &frame_number;
key[8].length = 0;
key[8].key = NULL;
}
timing_info = (timing_info_t *)wmem_tree_lookup32_array_le(timing, key);
if (timing_info && timing_info->interface_id == interface_id &&
timing_info->adapter_id == adapter_id &&
timing_info->chandle == chandle &&
timing_info->psm == psm &&
if (timing_info && timing_info->interface_id == avrcp_proto_data.interface_id &&
timing_info->adapter_id == avrcp_proto_data.adapter_id &&
timing_info->chandle == avrcp_proto_data.chandle &&
timing_info->psm == avrcp_proto_data.channel &&
timing_info->opcode == opcode &&
timing_info->op == op &&
((ctype == 0x0a) ? 1 : (timing_info->op_arg == op_arg))) {

View File

@ -362,31 +362,101 @@ dissect_bthcrp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
{
proto_item *main_item;
proto_tree *main_tree;
btl2cap_data_t *l2cap_data;
gint offset = 0;
gint protocol = -1;
wmem_tree_key_t key[10];
guint32 k_interface_id;
guint32 k_adapter_id;
guint32 k_sdp_psm;
guint32 k_direction;
guint32 k_bd_addr_oui;
guint32 k_bd_addr_id;
guint32 k_service_type;
guint32 k_service_channel;
guint32 k_frame_number;
guint32 interface_id;
guint32 adapter_id;
guint32 remote_bd_addr_oui;
guint32 remote_bd_addr_id;
service_info_t *service_info;
gboolean is_client_message = FALSE;
gint previous_proto;
gboolean is_client_message = FALSE;
previous_proto = (GPOINTER_TO_INT(wmem_list_frame_data(wmem_list_frame_prev(wmem_list_tail(pinfo->layers)))));
if (previous_proto == proto_btl2cap) {
btl2cap_data_t *l2cap_data;
wmem_tree_key_t key[10];
guint32 interface_id;
guint32 adapter_id;
guint32 sdp_psm = SDP_PSM_DEFAULT;
guint32 direction;
guint32 bd_addr_oui;
guint32 bd_addr_id;
guint32 service_type;
guint32 service_channel;
guint32 frame_number;
service_info_t *service_info;
/* Reject the packet if data is NULL */
if (data == NULL)
return 0;
l2cap_data = (btl2cap_data_t *) data;
l2cap_data = (btl2cap_data_t *) data;
interface_id = l2cap_data->interface_id;
adapter_id = l2cap_data->adapter_id;
direction = (l2cap_data->is_local_psm) ? P2P_DIR_SENT : P2P_DIR_RECV;
if (direction == P2P_DIR_RECV) {
bd_addr_oui = l2cap_data->remote_bd_addr_oui;
bd_addr_id = l2cap_data->remote_bd_addr_id;
} else {
bd_addr_oui = 0;
bd_addr_id = 0;
}
service_type = BTSDP_L2CAP_PROTOCOL_UUID;
service_channel = l2cap_data->psm;
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 = &sdp_psm;
key[3].length = 1;
key[3].key = &direction;
key[4].length = 1;
key[4].key = &bd_addr_oui;
key[5].length = 1;
key[5].key = &bd_addr_id;
key[6].length = 1;
key[6].key = &service_type;
key[7].length = 1;
key[7].key = &service_channel;
key[8].length = 1;
key[8].key = &frame_number;
key[9].length = 0;
key[9].key = NULL;
service_info = btsdp_get_service_info(key);
if (service_info && service_info->interface_id == interface_id &&
service_info->adapter_id == adapter_id &&
service_info->sdp_psm == SDP_PSM_DEFAULT &&
((service_info->direction == P2P_DIR_RECV &&
service_info->bd_addr_oui == bd_addr_oui &&
service_info->bd_addr_id == bd_addr_id) ||
(service_info->direction != P2P_DIR_RECV &&
service_info->bd_addr_oui == 0 &&
service_info->bd_addr_id == 0)) &&
service_info->type == BTSDP_L2CAP_PROTOCOL_UUID &&
service_info->channel == l2cap_data->psm) {
if ((service_info->protocol == BTSDP_HARDCOPY_CONTROL_CHANNEL_PROTOCOL_UUID ||
service_info->protocol == BTSDP_HARDCOPY_DATA_CHANNEL_PROTOCOL_UUID) &&
((!l2cap_data->is_local_psm && pinfo->p2p_dir == P2P_DIR_SENT) ||
(l2cap_data->is_local_psm && pinfo->p2p_dir == P2P_DIR_RECV))) {
is_client_message = TRUE;
} else if (service_info->protocol == BTSDP_HARDCOPY_NOTIFICATION_PROTOCOL_UUID &&
((l2cap_data->is_local_psm && pinfo->p2p_dir == P2P_DIR_SENT) ||
(!l2cap_data->is_local_psm && pinfo->p2p_dir == P2P_DIR_RECV))) {
is_client_message = TRUE;
}
protocol = service_info->protocol;
}
if (psm_control != 0 && l2cap_data->psm == psm_control) {
protocol = BTSDP_HARDCOPY_CONTROL_CHANNEL_PROTOCOL_UUID;
} else if (psm_data_stream != 0 && l2cap_data->psm == psm_data_stream) {
protocol = BTSDP_HARDCOPY_DATA_CHANNEL_PROTOCOL_UUID;
} else if (psm_notification != 0 && l2cap_data->psm == psm_notification) {
protocol = BTSDP_HARDCOPY_NOTIFICATION_PROTOCOL_UUID;
}
}
main_item = proto_tree_add_item(tree, proto_bthcrp, tvb, offset, -1, ENC_NA);
main_tree = proto_item_add_subtree(main_item, ett_bthcrp);
@ -405,92 +475,19 @@ dissect_bthcrp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
break;
}
interface_id = l2cap_data->interface_id;
adapter_id = l2cap_data->adapter_id;
k_interface_id = interface_id;
k_adapter_id = adapter_id;
k_sdp_psm = SDP_PSM_DEFAULT;
k_direction = (l2cap_data->is_local_psm) ? P2P_DIR_SENT : P2P_DIR_RECV;
if (k_direction == P2P_DIR_RECV) {
k_bd_addr_oui = l2cap_data->remote_bd_addr_oui;
k_bd_addr_id = l2cap_data->remote_bd_addr_id;
} else {
k_bd_addr_oui = 0;
k_bd_addr_id = 0;
}
remote_bd_addr_oui = k_bd_addr_oui;
remote_bd_addr_id = k_bd_addr_id;
k_service_type = BTSDP_L2CAP_PROTOCOL_UUID;
k_service_channel = l2cap_data->psm;
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_sdp_psm;
key[3].length = 1;
key[3].key = &k_direction;
key[4].length = 1;
key[4].key = &k_bd_addr_oui;
key[5].length = 1;
key[5].key = &k_bd_addr_id;
key[6].length = 1;
key[6].key = &k_service_type;
key[7].length = 1;
key[7].key = &k_service_channel;
key[8].length = 1;
key[8].key = &k_frame_number;
key[9].length = 0;
key[9].key = NULL;
service_info = btsdp_get_service_info(key);
if (service_info && service_info->interface_id == interface_id &&
service_info->adapter_id == adapter_id &&
service_info->sdp_psm == SDP_PSM_DEFAULT &&
((service_info->direction == P2P_DIR_RECV &&
service_info->bd_addr_oui == remote_bd_addr_oui &&
service_info->bd_addr_id == remote_bd_addr_id) ||
(service_info->direction != P2P_DIR_RECV &&
service_info->bd_addr_oui == 0 &&
service_info->bd_addr_id == 0)) &&
service_info->type == BTSDP_L2CAP_PROTOCOL_UUID &&
service_info->channel == l2cap_data->psm) {
if ((service_info->protocol == BTSDP_HARDCOPY_CONTROL_CHANNEL_PROTOCOL_UUID ||
service_info->protocol == BTSDP_HARDCOPY_DATA_CHANNEL_PROTOCOL_UUID) &&
((!l2cap_data->is_local_psm && pinfo->p2p_dir == P2P_DIR_SENT) ||
(l2cap_data->is_local_psm && pinfo->p2p_dir == P2P_DIR_RECV))) {
is_client_message = TRUE;
} else if (service_info->protocol == BTSDP_HARDCOPY_NOTIFICATION_PROTOCOL_UUID &&
((l2cap_data->is_local_psm && pinfo->p2p_dir == P2P_DIR_SENT) ||
(!l2cap_data->is_local_psm && pinfo->p2p_dir == P2P_DIR_RECV))) {
is_client_message = TRUE;
}
protocol = service_info->protocol;
}
if (force_client != FORCE_CLIENT_DEFAULT) {
is_client_message = (force_client == FORCE_CLIENT_YES && pinfo->p2p_dir == P2P_DIR_SENT) ||
(force_client != FORCE_CLIENT_YES && pinfo->p2p_dir == P2P_DIR_RECV);
}
if ((psm_control != 0 && l2cap_data->psm == psm_control) ||
(psm_control == 0 && protocol == BTSDP_HARDCOPY_CONTROL_CHANNEL_PROTOCOL_UUID)) {
if (protocol == BTSDP_HARDCOPY_CONTROL_CHANNEL_PROTOCOL_UUID) {
offset = dissect_control(tvb, pinfo, main_tree, offset, is_client_message);
} else if ((psm_data_stream != 0 && l2cap_data->psm == psm_data_stream) ||
(psm_data_stream == 0 && protocol == BTSDP_HARDCOPY_DATA_CHANNEL_PROTOCOL_UUID)) {
} else if (protocol == BTSDP_HARDCOPY_DATA_CHANNEL_PROTOCOL_UUID) {
offset = dissect_data(tvb, pinfo, main_tree, offset);
} else if ((psm_notification != 0 && l2cap_data->psm == psm_notification) ||
(psm_notification == 0 && protocol == BTSDP_HARDCOPY_NOTIFICATION_PROTOCOL_UUID)) {
} else if (protocol == BTSDP_HARDCOPY_NOTIFICATION_PROTOCOL_UUID) {
offset = dissect_notification(tvb, pinfo, main_tree, offset, is_client_message);
} else {
col_append_fstr(pinfo->cinfo, COL_INFO, "HCRP stream (CID: 0x%04X)", l2cap_data->cid);
col_append_fstr(pinfo->cinfo, COL_INFO, "HCRP stream");
}
if (tvb_reported_length_remaining(tvb, offset)) {

View File

@ -1866,20 +1866,17 @@ dissect_bthfp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
gint offset = 0;
guint32 role = ROLE_UNKNOWN;
wmem_tree_key_t key[10];
guint32 k_interface_id;
guint32 k_adapter_id;
guint32 k_chandle;
guint32 k_dlci;
guint32 k_role;
guint32 k_frame_number;
guint32 interface_id;
guint32 adapter_id;
guint32 chandle;
guint32 dlci;
guint32 frame_number;
guint32 direction;
guint32 bd_addr_oui;
guint32 bd_addr_id;
fragment_t *fragment;
fragment_t *previous_fragment;
fragment_t *i_fragment;
btrfcomm_data_t *rfcomm_data;
guint8 *at_stream;
gint length;
gint command_number;
@ -1887,13 +1884,39 @@ dissect_bthfp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
tvbuff_t *reassembled_tvb = NULL;
guint reassemble_start_offset = 0;
guint reassemble_end_offset = 0;
gint previous_proto;
/* Reject the packet if data is NULL */
if (data == NULL)
return 0;
rfcomm_data = (btrfcomm_data_t *) data;
previous_proto = (GPOINTER_TO_INT(wmem_list_frame_data(wmem_list_frame_prev(wmem_list_tail(pinfo->layers)))));
if (data && previous_proto == proto_btrfcomm) {
btrfcomm_data_t *rfcomm_data;
main_item = proto_tree_add_item(tree, proto_bthfp, tvb, 0, -1, ENC_NA);
rfcomm_data = (btrfcomm_data_t *) data;
interface_id = rfcomm_data->interface_id;
adapter_id = rfcomm_data->adapter_id;
chandle = rfcomm_data->chandle;
dlci = rfcomm_data->dlci;
direction = (rfcomm_data->is_local_psm) ? P2P_DIR_SENT : P2P_DIR_RECV;
if (direction == P2P_DIR_RECV) {
bd_addr_oui = rfcomm_data->remote_bd_addr_oui;
bd_addr_id = rfcomm_data->remote_bd_addr_id;
} else {
bd_addr_oui = 0;
bd_addr_id = 0;
}
} else {
interface_id = HCI_INTERFACE_DEFAULT;
adapter_id = HCI_ADAPTER_DEFAULT;
chandle = 0;
dlci = 0;
direction = P2P_DIR_UNKNOWN;
bd_addr_oui = 0;
bd_addr_id = 0;
}
main_item = proto_tree_add_item(tree, proto_bthfp, tvb, 0, tvb_captured_length(tvb), ENC_NA);
main_tree = proto_item_add_subtree(main_item, ett_bthfp);
col_set_str(pinfo->cinfo, COL_PROTOCOL, "HFP");
@ -1910,11 +1933,6 @@ dissect_bthfp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
break;
}
interface_id = rfcomm_data->interface_id;
adapter_id = rfcomm_data->adapter_id;
chandle = rfcomm_data->chandle;
dlci = rfcomm_data->dlci;
if ((hfp_role == ROLE_AG && pinfo->p2p_dir == P2P_DIR_SENT) ||
(hfp_role == ROLE_HS && pinfo->p2p_dir == P2P_DIR_RECV)) {
role = ROLE_AG;
@ -1923,62 +1941,50 @@ dissect_bthfp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
}
if (role == ROLE_UNKNOWN) {
guint32 k_sdp_psm;
guint32 k_direction;
guint32 k_bd_addr_oui;
guint32 k_bd_addr_id;
guint32 k_service_type;
guint32 k_service_channel;
guint32 sdp_psm;
guint32 service_type;
guint32 service_channel;
service_info_t *service_info;
k_interface_id = rfcomm_data->interface_id;
k_adapter_id = rfcomm_data->adapter_id;
k_sdp_psm = SDP_PSM_DEFAULT;
k_direction = (rfcomm_data->is_local_psm) ? P2P_DIR_SENT : P2P_DIR_RECV;
if (k_direction == P2P_DIR_RECV) {
k_bd_addr_oui = rfcomm_data->remote_bd_addr_oui;
k_bd_addr_id = rfcomm_data->remote_bd_addr_id;
} else {
k_bd_addr_oui = 0;
k_bd_addr_id = 0;
}
k_service_type = BTSDP_RFCOMM_PROTOCOL_UUID;
k_service_channel = rfcomm_data->dlci >> 1;
k_frame_number = pinfo->fd->num;
sdp_psm = SDP_PSM_DEFAULT;
service_type = BTSDP_RFCOMM_PROTOCOL_UUID;
service_channel = dlci >> 1;
frame_number = pinfo->fd->num;
key[0].length = 1;
key[0].key = &k_interface_id;
key[0].key = &interface_id;
key[1].length = 1;
key[1].key = &k_adapter_id;
key[1].key = &adapter_id;
key[2].length = 1;
key[2].key = &k_sdp_psm;
key[2].key = &sdp_psm;
key[3].length = 1;
key[3].key = &k_direction;
key[3].key = &direction;
key[4].length = 1;
key[4].key = &k_bd_addr_oui;
key[4].key = &bd_addr_oui;
key[5].length = 1;
key[5].key = &k_bd_addr_id;
key[5].key = &bd_addr_id;
key[6].length = 1;
key[6].key = &k_service_type;
key[6].key = &service_type;
key[7].length = 1;
key[7].key = &k_service_channel;
key[7].key = &service_channel;
key[8].length = 1;
key[8].key = &k_frame_number;
key[8].key = &frame_number;
key[9].length = 0;
key[9].key = NULL;
service_info = btsdp_get_service_info(key);
if (service_info && service_info->interface_id == rfcomm_data->interface_id &&
service_info->adapter_id == rfcomm_data->adapter_id &&
if (service_info && service_info->interface_id == interface_id &&
service_info->adapter_id == adapter_id &&
service_info->sdp_psm == SDP_PSM_DEFAULT &&
((service_info->direction == P2P_DIR_RECV &&
service_info->bd_addr_oui == rfcomm_data->remote_bd_addr_oui &&
service_info->bd_addr_id == rfcomm_data->remote_bd_addr_id) ||
service_info->bd_addr_oui == bd_addr_oui &&
service_info->bd_addr_id == bd_addr_id) ||
(service_info->direction != P2P_DIR_RECV &&
service_info->bd_addr_oui == 0 &&
service_info->bd_addr_id == 0)) &&
service_info->type == BTSDP_RFCOMM_PROTOCOL_UUID &&
service_info->channel == (rfcomm_data->dlci >> 1)) {
service_info->channel == (dlci >> 1)) {
if ((service_info->uuid.bt_uuid == BTSDP_HFP_GW_SERVICE_UUID && service_info->direction == P2P_DIR_RECV && pinfo->p2p_dir == P2P_DIR_SENT) ||
(service_info->uuid.bt_uuid == BTSDP_HFP_GW_SERVICE_UUID && service_info->direction == P2P_DIR_SENT && pinfo->p2p_dir == P2P_DIR_RECV) ||
(service_info->uuid.bt_uuid == BTSDP_HFP_SERVICE_UUID && service_info->direction == P2P_DIR_RECV && pinfo->p2p_dir == P2P_DIR_RECV) ||
@ -1996,31 +2002,26 @@ dissect_bthfp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
if (role == ROLE_UNKNOWN) {
col_append_fstr(pinfo->cinfo, COL_INFO, "Data: %s",
tvb_format_text(tvb, 0, tvb_reported_length(tvb)));
proto_tree_add_item(main_tree, hf_data, tvb, 0, -1, ENC_NA | ENC_ASCII);
proto_tree_add_item(main_tree, hf_data, tvb, 0, tvb_captured_length(tvb), ENC_NA | ENC_ASCII);
return tvb_reported_length(tvb);
}
/* save fragments */
if (!pinfo->fd->flags.visited) {
k_interface_id = interface_id;
k_adapter_id = adapter_id;
k_chandle = chandle;
k_dlci = dlci;
k_role = role;
k_frame_number = pinfo->fd->num - 1;
frame_number = pinfo->fd->num - 1;
key[0].length = 1;
key[0].key = &k_interface_id;
key[0].key = &interface_id;
key[1].length = 1;
key[1].key = &k_adapter_id;
key[1].key = &adapter_id;
key[2].length = 1;
key[2].key = &k_chandle;
key[2].key = &chandle;
key[3].length = 1;
key[3].key = &k_dlci;
key[3].key = &dlci;
key[4].length = 1;
key[4].key = &k_role;
key[4].key = &role;
key[5].length = 1;
key[5].key = &k_frame_number;
key[5].key = &frame_number;
key[6].length = 0;
key[6].key = NULL;
@ -2034,25 +2035,20 @@ dissect_bthfp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
previous_fragment = NULL;
}
k_interface_id = interface_id;
k_adapter_id = adapter_id;
k_chandle = chandle;
k_dlci = dlci;
k_role = role;
k_frame_number = pinfo->fd->num;
frame_number = pinfo->fd->num;
key[0].length = 1;
key[0].key = &k_interface_id;
key[0].key = &interface_id;
key[1].length = 1;
key[1].key = &k_adapter_id;
key[1].key = &adapter_id;
key[2].length = 1;
key[2].key = &k_chandle;
key[2].key = &chandle;
key[3].length = 1;
key[3].key = &k_dlci;
key[3].key = &dlci;
key[4].length = 1;
key[4].key = &k_role;
key[4].key = &role;
key[5].length = 1;
key[5].key = &k_frame_number;
key[5].key = &frame_number;
key[6].length = 0;
key[6].key = NULL;
@ -2092,25 +2088,20 @@ dissect_bthfp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
reassemble_start_offset = i_length + 1;
}
k_interface_id = interface_id;
k_adapter_id = adapter_id;
k_chandle = chandle;
k_dlci = dlci;
k_role = role;
k_frame_number = pinfo->fd->num;
frame_number = pinfo->fd->num;
key[0].length = 1;
key[0].key = &k_interface_id;
key[0].key = &interface_id;
key[1].length = 1;
key[1].key = &k_adapter_id;
key[1].key = &adapter_id;
key[2].length = 1;
key[2].key = &k_chandle;
key[2].key = &chandle;
key[3].length = 1;
key[3].key = &k_dlci;
key[3].key = &dlci;
key[4].length = 1;
key[4].key = &k_role;
key[4].key = &role;
key[5].length = 1;
key[5].key = &k_frame_number;
key[5].key = &frame_number;
key[6].length = 0;
key[6].key = NULL;
@ -2159,25 +2150,20 @@ dissect_bthfp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
}
/* recover reassembled payload */
k_interface_id = interface_id;
k_adapter_id = adapter_id;
k_chandle = chandle;
k_dlci = dlci;
k_role = role;
k_frame_number = pinfo->fd->num;
frame_number = pinfo->fd->num;
key[0].length = 1;
key[0].key = &k_interface_id;
key[0].key = &interface_id;
key[1].length = 1;
key[1].key = &k_adapter_id;
key[1].key = &adapter_id;
key[2].length = 1;
key[2].key = &k_chandle;
key[2].key = &chandle;
key[3].length = 1;
key[3].key = &k_dlci;
key[3].key = &dlci;
key[4].length = 1;
key[4].key = &k_role;
key[4].key = &role;
key[5].length = 1;
key[5].key = &k_frame_number;
key[5].key = &frame_number;
key[6].length = 0;
key[6].key = NULL;
@ -2221,7 +2207,7 @@ dissect_bthfp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
if (fragment->idx > 0 && fragment->length > 0) {
proto_tree_add_item(main_tree, hf_fragment, tvb, offset,
tvb_reported_length_remaining(tvb, offset), ENC_ASCII | ENC_NA);
tvb_captured_length_remaining(tvb, offset), ENC_ASCII | ENC_NA);
reassembled_tvb = tvb_new_child_real_data(tvb, at_data,
fragment->idx + fragment->length, fragment->idx + fragment->length);
add_new_data_source(pinfo, reassembled_tvb, "Reassembled HFP");
@ -2236,7 +2222,6 @@ dissect_bthfp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
pinfo, main_tree, reassembled_offset, role, command_number);
command_number += 1;
}
offset = tvb_captured_length(tvb);
} else {
while (tvb_reported_length(tvb) > (guint) offset) {

View File

@ -517,23 +517,23 @@ dissect_at_command(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
first_response_in (if 0 - no response)
k_interface_id = interface_id;
k_adapter_id = adapter_id;
k_chandle = chandle;
k_dlci = dlci;
k_frame_number = pinfo->fd->num;
interface_id = interface_id;
adapter_id = adapter_id;
chandle = chandle;
dlci = dlci;
frame_number = pinfo->fd->num;
key[0].length = 1;
key[0].key = &k_interface_id;
key[0].key = &interface_id;
key[1].length = 1;
key[1].key = &k_adapter_id;
key[1].key = &adapter_id;
key[2].length = 1;
key[2].key = &k_chandle;
key[2].key = &chandle;
key[3].length = 1;
key[3].key = &k_dlci;
key[3].key = &dlci;
key[4].length = 1;
key[4].key = &k_frame_number;
key[4].key = &frame_number;
key[5].length = 0;
key[5].key = NULL;
@ -634,20 +634,17 @@ dissect_bthsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
gint offset = 0;
guint32 role = ROLE_UNKNOWN;
wmem_tree_key_t key[10];
guint32 k_interface_id;
guint32 k_adapter_id;
guint32 k_chandle;
guint32 k_dlci;
guint32 k_role;
guint32 k_frame_number;
guint32 interface_id;
guint32 adapter_id;
guint32 chandle;
guint32 dlci;
guint32 frame_number;
guint32 direction;
guint32 bd_addr_oui;
guint32 bd_addr_id;
fragment_t *fragment;
fragment_t *previous_fragment;
fragment_t *i_fragment;
btrfcomm_data_t *rfcomm_data;
guint8 *at_stream;
gint length;
gint command_number;
@ -655,13 +652,39 @@ dissect_bthsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
tvbuff_t *reassembled_tvb = NULL;
guint reassemble_start_offset = 0;
guint reassemble_end_offset = 0;
gint previous_proto;
/* Reject the packet if data is NULL */
if (data == NULL)
return 0;
rfcomm_data = (btrfcomm_data_t *) data;
previous_proto = (GPOINTER_TO_INT(wmem_list_frame_data(wmem_list_frame_prev(wmem_list_tail(pinfo->layers)))));
if (data && previous_proto == proto_btrfcomm) {
btrfcomm_data_t *rfcomm_data;
main_item = proto_tree_add_item(tree, proto_bthsp, tvb, 0, -1, ENC_NA);
rfcomm_data = (btrfcomm_data_t *) data;
interface_id = rfcomm_data->interface_id;
adapter_id = rfcomm_data->adapter_id;
chandle = rfcomm_data->chandle;
dlci = rfcomm_data->dlci;
direction = (rfcomm_data->is_local_psm) ? P2P_DIR_SENT : P2P_DIR_RECV;
if (direction == P2P_DIR_RECV) {
bd_addr_oui = rfcomm_data->remote_bd_addr_oui;
bd_addr_id = rfcomm_data->remote_bd_addr_id;
} else {
bd_addr_oui = 0;
bd_addr_id = 0;
}
} else {
interface_id = HCI_INTERFACE_DEFAULT;
adapter_id = HCI_ADAPTER_DEFAULT;
chandle = 0;
dlci = 0;
direction = P2P_DIR_UNKNOWN;
bd_addr_oui = 0;
bd_addr_id = 0;
}
main_item = proto_tree_add_item(tree, proto_bthsp, tvb, 0, tvb_captured_length(tvb), ENC_NA);
main_tree = proto_item_add_subtree(main_item, ett_bthsp);
col_set_str(pinfo->cinfo, COL_PROTOCOL, "HSP");
@ -678,11 +701,6 @@ dissect_bthsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
break;
}
interface_id = rfcomm_data->interface_id;
adapter_id = rfcomm_data->adapter_id;
chandle = rfcomm_data->chandle;
dlci = rfcomm_data->dlci;
if ((hsp_role == ROLE_AG && pinfo->p2p_dir == P2P_DIR_SENT) ||
(hsp_role == ROLE_HS && pinfo->p2p_dir == P2P_DIR_RECV)) {
role = ROLE_AG;
@ -691,62 +709,50 @@ dissect_bthsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
}
if (role == ROLE_UNKNOWN) {
guint32 k_sdp_psm;
guint32 k_direction;
guint32 k_bd_addr_oui;
guint32 k_bd_addr_id;
guint32 k_service_type;
guint32 k_service_channel;
guint32 sdp_psm;
guint32 service_type;
guint32 service_channel;
service_info_t *service_info;
k_interface_id = rfcomm_data->interface_id;
k_adapter_id = rfcomm_data->adapter_id;
k_sdp_psm = SDP_PSM_DEFAULT;
k_direction = (rfcomm_data->is_local_psm) ? P2P_DIR_SENT : P2P_DIR_RECV;
if (k_direction == P2P_DIR_RECV) {
k_bd_addr_oui = rfcomm_data->remote_bd_addr_oui;
k_bd_addr_id = rfcomm_data->remote_bd_addr_id;
} else {
k_bd_addr_oui = 0;
k_bd_addr_id = 0;
}
k_service_type = BTSDP_RFCOMM_PROTOCOL_UUID;
k_service_channel = rfcomm_data->dlci >> 1;
k_frame_number = pinfo->fd->num;
sdp_psm = SDP_PSM_DEFAULT;
service_type = BTSDP_RFCOMM_PROTOCOL_UUID;
service_channel = dlci >> 1;
frame_number = pinfo->fd->num;
key[0].length = 1;
key[0].key = &k_interface_id;
key[0].key = &interface_id;
key[1].length = 1;
key[1].key = &k_adapter_id;
key[1].key = &adapter_id;
key[2].length = 1;
key[2].key = &k_sdp_psm;
key[2].key = &sdp_psm;
key[3].length = 1;
key[3].key = &k_direction;
key[3].key = &direction;
key[4].length = 1;
key[4].key = &k_bd_addr_oui;
key[4].key = &bd_addr_oui;
key[5].length = 1;
key[5].key = &k_bd_addr_id;
key[5].key = &bd_addr_id;
key[6].length = 1;
key[6].key = &k_service_type;
key[6].key = &service_type;
key[7].length = 1;
key[7].key = &k_service_channel;
key[7].key = &service_channel;
key[8].length = 1;
key[8].key = &k_frame_number;
key[8].key = &frame_number;
key[9].length = 0;
key[9].key = NULL;
service_info = btsdp_get_service_info(key);
if (service_info && service_info->interface_id == rfcomm_data->interface_id &&
service_info->adapter_id == rfcomm_data->adapter_id &&
if (service_info && service_info->interface_id == interface_id &&
service_info->adapter_id == adapter_id &&
service_info->sdp_psm == SDP_PSM_DEFAULT &&
((service_info->direction == P2P_DIR_RECV &&
service_info->bd_addr_oui == rfcomm_data->remote_bd_addr_oui &&
service_info->bd_addr_id == rfcomm_data->remote_bd_addr_id) ||
service_info->bd_addr_oui == bd_addr_oui &&
service_info->bd_addr_id == bd_addr_id) ||
(service_info->direction != P2P_DIR_RECV &&
service_info->bd_addr_oui == 0 &&
service_info->bd_addr_id == 0)) &&
service_info->type == BTSDP_RFCOMM_PROTOCOL_UUID &&
service_info->channel == (rfcomm_data->dlci >> 1)) {
service_info->channel == (dlci >> 1)) {
if ((service_info->uuid.bt_uuid == BTSDP_HSP_GW_SERVICE_UUID && service_info->direction == P2P_DIR_RECV && pinfo->p2p_dir == P2P_DIR_SENT) ||
(service_info->uuid.bt_uuid == BTSDP_HSP_GW_SERVICE_UUID && service_info->direction == P2P_DIR_SENT && pinfo->p2p_dir == P2P_DIR_RECV) ||
((service_info->uuid.bt_uuid == BTSDP_HSP_SERVICE_UUID || service_info->uuid.bt_uuid == BTSDP_HSP_HS_SERVICE_UUID) && service_info->direction == P2P_DIR_RECV && pinfo->p2p_dir == P2P_DIR_RECV) ||
@ -764,31 +770,26 @@ dissect_bthsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
if (role == ROLE_UNKNOWN) {
col_append_fstr(pinfo->cinfo, COL_INFO, "Data: %s",
tvb_format_text(tvb, 0, tvb_reported_length(tvb)));
proto_tree_add_item(main_tree, hf_data, tvb, 0, tvb_reported_length(tvb), ENC_NA | ENC_ASCII);
proto_tree_add_item(main_tree, hf_data, tvb, 0, tvb_captured_length(tvb), ENC_NA | ENC_ASCII);
return tvb_reported_length(tvb);
}
/* save fragments */
if (!pinfo->fd->flags.visited) {
k_interface_id = interface_id;
k_adapter_id = adapter_id;
k_chandle = chandle;
k_dlci = dlci;
k_role = role;
k_frame_number = pinfo->fd->num - 1;
frame_number = pinfo->fd->num - 1;
key[0].length = 1;
key[0].key = &k_interface_id;
key[0].key = &interface_id;
key[1].length = 1;
key[1].key = &k_adapter_id;
key[1].key = &adapter_id;
key[2].length = 1;
key[2].key = &k_chandle;
key[2].key = &chandle;
key[3].length = 1;
key[3].key = &k_dlci;
key[3].key = &dlci;
key[4].length = 1;
key[4].key = &k_role;
key[4].key = &role;
key[5].length = 1;
key[5].key = &k_frame_number;
key[5].key = &frame_number;
key[6].length = 0;
key[6].key = NULL;
@ -802,25 +803,20 @@ dissect_bthsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
previous_fragment = NULL;
}
k_interface_id = interface_id;
k_adapter_id = adapter_id;
k_chandle = chandle;
k_dlci = dlci;
k_role = role;
k_frame_number = pinfo->fd->num;
frame_number = pinfo->fd->num;
key[0].length = 1;
key[0].key = &k_interface_id;
key[0].key = &interface_id;
key[1].length = 1;
key[1].key = &k_adapter_id;
key[1].key = &adapter_id;
key[2].length = 1;
key[2].key = &k_chandle;
key[2].key = &chandle;
key[3].length = 1;
key[3].key = &k_dlci;
key[3].key = &dlci;
key[4].length = 1;
key[4].key = &k_role;
key[4].key = &role;
key[5].length = 1;
key[5].key = &k_frame_number;
key[5].key = &frame_number;
key[6].length = 0;
key[6].key = NULL;
@ -830,7 +826,7 @@ dissect_bthsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
fragment->chandle = chandle;
fragment->dlci = dlci;
fragment->role = role;
fragment->idx = previous_fragment ? previous_fragment->idx + previous_fragment->length : 0;
fragment->idx = previous_fragment ? previous_fragment->idx + previous_fragment->length : 0;
fragment->reassemble_state = REASSEMBLE_FRAGMENT;
fragment->length = tvb_reported_length(tvb);
fragment->data = (guint8 *) wmem_alloc(wmem_file_scope(), fragment->length);
@ -860,25 +856,20 @@ dissect_bthsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
reassemble_start_offset = i_length + 1;
}
k_interface_id = interface_id;
k_adapter_id = adapter_id;
k_chandle = chandle;
k_dlci = dlci;
k_role = role;
k_frame_number = pinfo->fd->num;
frame_number = pinfo->fd->num;
key[0].length = 1;
key[0].key = &k_interface_id;
key[0].key = &interface_id;
key[1].length = 1;
key[1].key = &k_adapter_id;
key[1].key = &adapter_id;
key[2].length = 1;
key[2].key = &k_chandle;
key[2].key = &chandle;
key[3].length = 1;
key[3].key = &k_dlci;
key[3].key = &dlci;
key[4].length = 1;
key[4].key = &k_role;
key[4].key = &role;
key[5].length = 1;
key[5].key = &k_frame_number;
key[5].key = &frame_number;
key[6].length = 0;
key[6].key = NULL;
@ -917,7 +908,8 @@ dissect_bthsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
i_fragment->data[1] == '\n') {
fragment->reassemble_state = REASSEMBLE_DONE;
} else if (role == ROLE_HS) {
fragment->reassemble_state = REASSEMBLE_PARTIALLY;
/* XXX: Temporary disable reassembling of partial message, it seems to be broken */
/* fragment->reassemble_state = REASSEMBLE_PARTIALLY;*/
}
fragment->reassemble_start_offset = reassemble_start_offset;
fragment->reassemble_end_offset = reassemble_end_offset;
@ -926,25 +918,20 @@ dissect_bthsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
}
/* recover reassembled payload */
k_interface_id = interface_id;
k_adapter_id = adapter_id;
k_chandle = chandle;
k_dlci = dlci;
k_role = role;
k_frame_number = pinfo->fd->num;
frame_number = pinfo->fd->num;
key[0].length = 1;
key[0].key = &k_interface_id;
key[0].key = &interface_id;
key[1].length = 1;
key[1].key = &k_adapter_id;
key[1].key = &adapter_id;
key[2].length = 1;
key[2].key = &k_chandle;
key[2].key = &chandle;
key[3].length = 1;
key[3].key = &k_dlci;
key[3].key = &dlci;
key[4].length = 1;
key[4].key = &k_role;
key[4].key = &role;
key[5].length = 1;
key[5].key = &k_frame_number;
key[5].key = &frame_number;
key[6].length = 0;
key[6].key = NULL;
@ -964,9 +951,8 @@ dissect_bthsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
i_fragment = fragment;
if (i_fragment && i_fragment->reassemble_state == REASSEMBLE_PARTIALLY) {
i_data_offset -= i_fragment->reassemble_end_offset;
memcpy(at_data + i_data_offset, i_fragment->data, i_fragment->reassemble_end_offset);
i_data_offset -= i_fragment->reassemble_end_offset;
memcpy(at_data + i_data_offset, i_fragment->data, i_fragment->reassemble_end_offset);
i_fragment = i_fragment->previous_fragment;
}
@ -989,7 +975,7 @@ dissect_bthsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
if (fragment->idx > 0 && fragment->length > 0) {
proto_tree_add_item(main_tree, hf_fragment, tvb, offset,
tvb_reported_length_remaining(tvb, offset), ENC_ASCII | ENC_NA);
tvb_captured_length_remaining(tvb, offset), ENC_ASCII | ENC_NA);
reassembled_tvb = tvb_new_child_real_data(tvb, at_data,
fragment->idx + fragment->length, fragment->idx + fragment->length);
add_new_data_source(pinfo, reassembled_tvb, "Reassembled HSP");
@ -1004,6 +990,7 @@ dissect_bthsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
pinfo, main_tree, reassembled_offset, role, command_number);
command_number += 1;
}
offset = tvb_captured_length(tvb);
} else {
while (tvb_reported_length(tvb) > (guint) offset) {
offset = dissect_at_command(tvb, pinfo, main_tree, offset, role, command_number);
@ -1012,11 +999,12 @@ dissect_bthsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
}
} else {
col_append_fstr(pinfo->cinfo, COL_INFO, "Fragment: %s",
tvb_format_text_wsp(tvb, offset, tvb_reported_length_remaining(tvb, offset)));
tvb_format_text_wsp(tvb, offset, tvb_captured_length_remaining(tvb, offset)));
pitem = proto_tree_add_item(main_tree, hf_fragmented, tvb, 0, 0, ENC_NA);
PROTO_ITEM_SET_GENERATED(pitem);
proto_tree_add_item(main_tree, hf_fragment, tvb, offset,
tvb_reported_length_remaining(tvb, offset), ENC_ASCII | ENC_NA);
tvb_captured_length_remaining(tvb, offset), ENC_ASCII | ENC_NA);
offset = tvb_captured_length(tvb);
}
return offset;

View File

@ -415,6 +415,13 @@ static dissector_handle_t data_text_lines_handle;
static const gchar *path_unknown = "?";
static const gchar *path_root = "/";
typedef struct _obex_proto_data_t {
guint32 interface_id;
guint32 adapter_id;
guint32 chandle;
guint32 channel;
} obex_proto_data_t;
typedef struct _ext_value_string {
guint8 value[16];
gint length;
@ -424,8 +431,8 @@ typedef struct _ext_value_string {
typedef struct _obex_path_data_t {
guint32 interface_id;
guint32 adapter_id;
guint16 chandle;
guint8 channel;
guint32 chandle;
guint32 channel;
/* TODO: add OBEX ConnectionId */
const gchar *path;
@ -434,8 +441,8 @@ typedef struct _obex_path_data_t {
typedef struct _obex_profile_data_t {
guint32 interface_id;
guint32 adapter_id;
guint16 chandle;
guint8 channel;
guint32 chandle;
guint32 channel;
/* TODO: add OBEX ConnectionId */
gint profile;
@ -444,8 +451,8 @@ typedef struct _obex_profile_data_t {
typedef struct _obex_last_opcode_data_t {
guint32 interface_id;
guint32 adapter_id;
guint16 chandle;
guint8 channel;
guint32 chandle;
guint32 channel;
/* TODO: add OBEX ConnectionId */
gint code;
@ -998,68 +1005,39 @@ void proto_register_btobex(void);
void proto_reg_handoff_btobex(void);
static void
save_path(packet_info *pinfo, const gchar *current_path, const gchar *name, gboolean go_up, int is_obex_over_l2cap, void *data)
save_path(packet_info *pinfo, const gchar *current_path, const gchar *name,
gboolean go_up, obex_proto_data_t *obex_proto_data)
{
/* On Connect response sets "/"
On SetPath sets what is needed
*/
if (!pinfo->fd->flags.visited && data) {
if (!pinfo->fd->flags.visited) {
obex_path_data_t *obex_path_data;
guint32 interface_id;
guint32 adapter_id;
guint32 chandle;
guint32 channel;
wmem_tree_key_t key[6];
guint32 k_interface_id;
guint32 k_adapter_id;
guint32 k_frame_number;
guint32 k_chandle;
guint32 k_channel;
guint32 frame_number;
const gchar *path = path_unknown;
if (is_obex_over_l2cap) {
btl2cap_data_t *l2cap_data;
l2cap_data = (btl2cap_data_t *) data;
interface_id = l2cap_data->interface_id;
adapter_id = l2cap_data->adapter_id;
chandle = l2cap_data->chandle;
channel = l2cap_data->cid;
} else {
btrfcomm_data_t *rfcomm_data;
rfcomm_data = (btrfcomm_data_t *) data;
interface_id = rfcomm_data->interface_id;
adapter_id = rfcomm_data->adapter_id;
chandle = rfcomm_data->chandle;
channel = rfcomm_data->dlci >> 1;
}
k_interface_id = interface_id;
k_adapter_id = adapter_id;
k_chandle = chandle;
k_channel = channel;
k_frame_number = pinfo->fd->num;
frame_number = pinfo->fd->num;
key[0].length = 1;
key[0].key = &k_interface_id;
key[0].key = &obex_proto_data->interface_id;
key[1].length = 1;
key[1].key = &k_adapter_id;
key[1].key = &obex_proto_data->adapter_id;
key[2].length = 1;
key[2].key = &k_chandle;
key[2].key = &obex_proto_data->chandle;
key[3].length = 1;
key[3].key = &k_channel;
key[3].key = &obex_proto_data->channel;
key[4].length = 1;
key[4].key = &k_frame_number;
key[4].key = &frame_number;
key[5].length = 0;
key[5].key = NULL;
obex_path_data = wmem_new(wmem_file_scope(), obex_path_data_t);
obex_path_data->interface_id = interface_id;
obex_path_data->adapter_id = adapter_id;
obex_path_data->chandle = chandle;
obex_path_data->channel = channel;
obex_path_data->interface_id = obex_proto_data->interface_id;
obex_path_data->adapter_id = obex_proto_data->adapter_id;
obex_path_data->chandle = obex_proto_data->chandle;
obex_path_data->channel = obex_proto_data->channel;
if (go_up == TRUE) {
if (current_path != path_unknown && current_path != path_root) {
@ -1775,7 +1753,8 @@ dissect_btobex_application_parameter_ctn(tvbuff_t *tvb, packet_info *pinfo, prot
static int
dissect_headers(proto_tree *tree, tvbuff_t *tvb, int offset, packet_info *pinfo,
gint profile, gboolean is_obex_over_l2cap, obex_last_opcode_data_t *obex_last_opcode_data, void *data)
gint profile, obex_last_opcode_data_t *obex_last_opcode_data,
obex_proto_data_t *obex_proto_data)
{
proto_tree *hdrs_tree = NULL;
proto_tree *hdr_tree = NULL;
@ -1787,30 +1766,9 @@ dissect_headers(proto_tree *tree, tvbuff_t *tvb, int offset, packet_info *pinfo,
gint value_length = 0;
guint8 hdr_id, i;
guint32 value;
guint32 frame_number;
guint8 tag;
gchar *str = NULL;
guint32 interface_id;
guint32 adapter_id;
guint32 chandle;
guint32 channel;
if (is_obex_over_l2cap) {
btl2cap_data_t *l2cap_data;
l2cap_data = (btl2cap_data_t *) data;
interface_id = l2cap_data->interface_id;
adapter_id = l2cap_data->adapter_id;
chandle = l2cap_data->chandle;
channel = l2cap_data->cid;
} else {
btrfcomm_data_t *rfcomm_data;
rfcomm_data = (btrfcomm_data_t *) data;
interface_id = rfcomm_data->interface_id;
adapter_id = rfcomm_data->adapter_id;
chandle = rfcomm_data->chandle;
channel = rfcomm_data->dlci >> 1;
}
if (tvb_reported_length_remaining(tvb, offset) > 0) {
proto_item *hdrs;
@ -1885,7 +1843,7 @@ dissect_headers(proto_tree *tree, tvbuff_t *tvb, int offset, packet_info *pinfo,
switch (hdr_id) {
case 0x4c: /* Application Parameters */
next_tvb = tvb_new_subset_length(tvb, offset, value_length);
if (!(new_offset = dissector_try_uint_new(btobex_profile, profile, next_tvb, pinfo, hdr_tree, TRUE, data))) {
if (!(new_offset = dissector_try_uint_new(btobex_profile, profile, next_tvb, pinfo, hdr_tree, TRUE, NULL))) {
new_offset = call_dissector(raw_application_parameters_handle, next_tvb, pinfo, hdr_tree);
}
offset += new_offset;
@ -2024,7 +1982,7 @@ dissect_headers(proto_tree *tree, tvbuff_t *tvb, int offset, packet_info *pinfo,
if (value_length > 0 && obex_last_opcode_data &&
(obex_last_opcode_data->code == BTOBEX_CODE_VALS_GET || obex_last_opcode_data->code == BTOBEX_CODE_VALS_PUT) &&
obex_last_opcode_data->data.get_put.type &&
dissector_try_string(media_type_dissector_table, obex_last_opcode_data->data.get_put.type, next_tvb, pinfo, tree, data) > 0) {
dissector_try_string(media_type_dissector_table, obex_last_opcode_data->data.get_put.type, next_tvb, pinfo, tree, NULL) > 0) {
offset += value_length;
} else {
if (!tvb_strneql(tvb, offset, "<?xml", 5))
@ -2052,37 +2010,27 @@ dissect_headers(proto_tree *tree, tvbuff_t *tvb, int offset, packet_info *pinfo,
obex_profile_data_t *obex_profile_data;
wmem_tree_key_t key[6];
guint32 k_interface_id;
guint32 k_adapter_id;
guint32 k_frame_number;
guint32 k_chandle;
guint32 k_channel;
k_interface_id = interface_id;
k_adapter_id = adapter_id;
k_chandle = chandle;
k_channel = channel;
k_frame_number = pinfo->fd->num;
frame_number = pinfo->fd->num;
key[0].length = 1;
key[0].key = &k_interface_id;
key[0].key = &obex_proto_data->interface_id;
key[1].length = 1;
key[1].key = &k_adapter_id;
key[1].key = &obex_proto_data->adapter_id;
key[2].length = 1;
key[2].key = &k_chandle;
key[2].key = &obex_proto_data->chandle;
key[3].length = 1;
key[3].key = &k_channel;
key[3].key = &obex_proto_data->channel;
key[4].length = 1;
key[4].key = &k_frame_number;
key[4].key = &frame_number;
key[5].length = 0;
key[5].key = NULL;
obex_profile_data = wmem_new(wmem_file_scope(), obex_profile_data_t);
obex_profile_data->interface_id = interface_id;
obex_profile_data->adapter_id = adapter_id;
obex_profile_data->chandle = chandle;
obex_profile_data->channel = channel;
obex_profile_data->profile = target_to_profile[i];
obex_profile_data->interface_id = obex_proto_data->interface_id;
obex_profile_data->adapter_id = obex_proto_data->adapter_id;
obex_profile_data->chandle = obex_proto_data->chandle;
obex_profile_data->channel = obex_proto_data->channel;
obex_profile_data->profile = target_to_profile[i];
wmem_tree_insert32_array(obex_profile, key, obex_profile_data);
}
@ -2141,7 +2089,7 @@ dissect_headers(proto_tree *tree, tvbuff_t *tvb, int offset, packet_info *pinfo,
switch (tag) {
case 0x00: /* Device Address */
if (sub_parameter_length == 6) {
offset = dissect_bd_addr(hf_sender_bd_addr, pinfo, parameter_tree, tvb, offset, FALSE, interface_id, adapter_id, NULL);
offset = dissect_bd_addr(hf_sender_bd_addr, pinfo, parameter_tree, tvb, offset, FALSE, obex_proto_data->interface_id, obex_proto_data->adapter_id, NULL);
} else {
proto_tree_add_item(parameter_tree, hf_session_parameter_data, tvb, offset, sub_parameter_length, ENC_NA);
@ -2296,34 +2244,50 @@ dissect_btobex(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
proto_tree *main_tree;
proto_item *sub_item;
fragment_head *frag_msg = NULL;
gboolean save_fragmented, complete;
gboolean save_fragmented;
gboolean complete;
tvbuff_t* new_tvb = NULL;
tvbuff_t* next_tvb = NULL;
gint offset = 0;
gint profile = PROFILE_UNKNOWN;
const gchar *path = path_unknown;
gboolean is_obex_over_l2cap = FALSE;
obex_profile_data_t *obex_profile_data;
guint32 interface_id;
guint32 adapter_id;
guint32 chandle;
guint32 channel;
wmem_tree_key_t key[6];
guint32 k_interface_id;
guint32 k_adapter_id;
guint32 k_frame_number;
guint32 k_chandle;
guint32 k_channel;
obex_profile_data_t *obex_profile_data;
wmem_tree_key_t key[6];
guint32 frame_number;
obex_last_opcode_data_t *obex_last_opcode_data;
obex_path_data_t *obex_path_data;
guint32 length;
guint8 *profile_data;
dissector_handle_t current_handle;
dissector_handle_t default_handle;
gint previous_proto;
obex_proto_data_t obex_proto_data;
/* Reject the packet if data is NULL */
if (data == NULL)
return 0;
previous_proto = (GPOINTER_TO_INT(wmem_list_frame_data(wmem_list_frame_prev(wmem_list_tail(pinfo->layers)))));
if (previous_proto == proto_btl2cap) {
btl2cap_data_t *l2cap_data;
l2cap_data = (btl2cap_data_t *) data;
obex_proto_data.interface_id = l2cap_data->interface_id;
obex_proto_data.adapter_id = l2cap_data->adapter_id;
obex_proto_data.chandle = l2cap_data->chandle;
obex_proto_data.channel = l2cap_data->cid;
} else if (previous_proto == proto_btrfcomm) {
btrfcomm_data_t *rfcomm_data;
rfcomm_data = (btrfcomm_data_t *) data;
obex_proto_data.interface_id = rfcomm_data->interface_id;
obex_proto_data.adapter_id = rfcomm_data->adapter_id;
obex_proto_data.chandle = rfcomm_data->chandle;
obex_proto_data.channel = rfcomm_data->dlci >> 1;
} else {
obex_proto_data.interface_id = HCI_INTERFACE_DEFAULT;
obex_proto_data.adapter_id = HCI_ADAPTER_DEFAULT;
obex_proto_data.chandle = 0;
obex_proto_data.channel = 0;
}
col_set_str(pinfo->cinfo, COL_PROTOCOL, "OBEX");
@ -2332,55 +2296,28 @@ dissect_btobex(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
save_fragmented = pinfo->fragmented;
is_obex_over_l2cap = (proto_btl2cap == (gint) GPOINTER_TO_UINT(wmem_list_frame_data(
wmem_list_frame_prev(wmem_list_tail(pinfo->layers)))));
if (is_obex_over_l2cap) {
btl2cap_data_t *l2cap_data;
l2cap_data = (btl2cap_data_t *) data;
interface_id = l2cap_data->interface_id;
adapter_id = l2cap_data->adapter_id;
chandle = l2cap_data->chandle;
channel = l2cap_data->cid;
} else {
btrfcomm_data_t *rfcomm_data;
rfcomm_data = (btrfcomm_data_t *) data;
interface_id = rfcomm_data->interface_id;
adapter_id = rfcomm_data->adapter_id;
chandle = rfcomm_data->chandle;
channel = rfcomm_data->dlci >> 1;
}
k_interface_id = interface_id;
k_adapter_id = adapter_id;
k_chandle = chandle;
k_channel = channel;
k_frame_number = pinfo->fd->num;
frame_number = pinfo->fd->num;
key[0].length = 1;
key[0].key = &k_interface_id;
key[0].key = &obex_proto_data.interface_id;
key[1].length = 1;
key[1].key = &k_adapter_id;
key[1].key = &obex_proto_data.adapter_id;
key[2].length = 1;
key[2].key = &k_chandle;
key[2].key = &obex_proto_data.chandle;
key[3].length = 1;
key[3].key = &k_channel;
key[3].key = &obex_proto_data.channel;
key[4].length = 1;
key[4].key = &k_frame_number;
key[4].key = &frame_number;
key[5].length = 0;
key[5].key = NULL;
profile_data = (guint8 *) p_get_proto_data(pinfo->pool, pinfo, proto_btobex, PROTO_DATA_BTOBEX_PROFILE);
if (profile_data == NULL) {
obex_profile_data = (obex_profile_data_t *)wmem_tree_lookup32_array_le(obex_profile, key);
if (obex_profile_data && obex_profile_data->interface_id == interface_id &&
obex_profile_data->adapter_id == adapter_id &&
obex_profile_data->chandle == chandle &&
obex_profile_data->channel == channel) {
if (obex_profile_data && obex_profile_data->interface_id == obex_proto_data.interface_id &&
obex_profile_data->adapter_id == obex_proto_data.adapter_id &&
obex_profile_data->chandle == obex_proto_data.chandle &&
obex_profile_data->channel == obex_proto_data.channel) {
profile = obex_profile_data->profile;
}
@ -2391,10 +2328,10 @@ dissect_btobex(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
}
obex_path_data = (obex_path_data_t *)wmem_tree_lookup32_array_le(obex_path, key);
if (obex_path_data && obex_path_data->interface_id == interface_id &&
obex_path_data->adapter_id == adapter_id &&
obex_path_data->chandle == chandle &&
obex_path_data->channel == channel) {
if (obex_path_data && obex_path_data->interface_id == obex_proto_data.interface_id &&
obex_path_data->adapter_id == obex_proto_data.adapter_id &&
obex_path_data->chandle == obex_proto_data.chandle &&
obex_path_data->channel == obex_proto_data.channel) {
path = obex_path_data->path;
}
@ -2514,52 +2451,29 @@ dissect_btobex(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
if (!pinfo->fd->flags.visited &&
(pinfo->p2p_dir == P2P_DIR_SENT ||
pinfo->p2p_dir == P2P_DIR_RECV)) {
if (is_obex_over_l2cap) {
btl2cap_data_t *l2cap_data;
l2cap_data = (btl2cap_data_t *) data;
interface_id = l2cap_data->interface_id;
adapter_id = l2cap_data->adapter_id;
chandle = l2cap_data->chandle;
channel = l2cap_data->cid;
} else {
btrfcomm_data_t *rfcomm_data;
rfcomm_data = (btrfcomm_data_t *) data;
interface_id = rfcomm_data->interface_id;
adapter_id = rfcomm_data->adapter_id;
chandle = rfcomm_data->chandle;
channel = rfcomm_data->dlci >> 1;
}
k_interface_id = interface_id;
k_adapter_id = adapter_id;
k_chandle = chandle;
k_channel = channel;
k_frame_number = pinfo->fd->num;
frame_number = pinfo->fd->num;
key[0].length = 1;
key[0].key = &k_interface_id;
key[0].key = &obex_proto_data.interface_id;
key[1].length = 1;
key[1].key = &k_adapter_id;
key[1].key = &obex_proto_data.adapter_id;
key[2].length = 1;
key[2].key = &k_chandle;
key[2].key = &obex_proto_data.chandle;
key[3].length = 1;
key[3].key = &k_channel;
key[3].key = &obex_proto_data.channel;
key[4].length = 1;
key[4].key = &k_frame_number;
key[4].key = &frame_number;
key[5].length = 0;
key[5].key = NULL;
obex_last_opcode_data = wmem_new0(wmem_file_scope(), obex_last_opcode_data_t);
obex_last_opcode_data->interface_id = interface_id;
obex_last_opcode_data->adapter_id = adapter_id;
obex_last_opcode_data->chandle = chandle;
obex_last_opcode_data->channel = channel;
obex_last_opcode_data->code = code;
obex_last_opcode_data->final_flag = final_flag;
obex_last_opcode_data->request_in_frame = k_frame_number;
obex_last_opcode_data->interface_id = obex_proto_data.interface_id;
obex_last_opcode_data->adapter_id = obex_proto_data.adapter_id;
obex_last_opcode_data->chandle = obex_proto_data.chandle;
obex_last_opcode_data->channel = obex_proto_data.channel;
obex_last_opcode_data->code = code;
obex_last_opcode_data->final_flag = final_flag;
obex_last_opcode_data->request_in_frame = frame_number;
obex_last_opcode_data->response_in_frame = 0;
wmem_tree_insert32_array(obex_last_opcode, key, obex_last_opcode_data);
@ -2576,49 +2490,26 @@ dissect_btobex(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
length = tvb_get_ntohs(tvb, offset) - 3;
offset += 2;
if (is_obex_over_l2cap) {
btl2cap_data_t *l2cap_data;
l2cap_data = (btl2cap_data_t *) data;
interface_id = l2cap_data->interface_id;
adapter_id = l2cap_data->adapter_id;
chandle = l2cap_data->chandle;
channel = l2cap_data->cid;
} else {
btrfcomm_data_t *rfcomm_data;
rfcomm_data = (btrfcomm_data_t *) data;
interface_id = rfcomm_data->interface_id;
adapter_id = rfcomm_data->adapter_id;
chandle = rfcomm_data->chandle;
channel = rfcomm_data->dlci >> 1;
}
k_interface_id = interface_id;
k_adapter_id = adapter_id;
k_chandle = chandle;
k_channel = channel;
k_frame_number = pinfo->fd->num;
frame_number = pinfo->fd->num;
key[0].length = 1;
key[0].key = &k_interface_id;
key[0].key = &obex_proto_data.interface_id;
key[1].length = 1;
key[1].key = &k_adapter_id;
key[1].key = &obex_proto_data.adapter_id;
key[2].length = 1;
key[2].key = &k_chandle;
key[2].key = &obex_proto_data.chandle;
key[3].length = 1;
key[3].key = &k_channel;
key[3].key = &obex_proto_data.channel;
key[4].length = 1;
key[4].key = &k_frame_number;
key[4].key = &frame_number;
key[5].length = 0;
key[5].key = NULL;
obex_last_opcode_data = (obex_last_opcode_data_t *)wmem_tree_lookup32_array_le(obex_last_opcode, key);
if (obex_last_opcode_data && obex_last_opcode_data->interface_id == interface_id &&
obex_last_opcode_data->adapter_id == adapter_id &&
obex_last_opcode_data->chandle == chandle &&
obex_last_opcode_data->channel == channel) {
if (obex_last_opcode_data && obex_last_opcode_data->interface_id == obex_proto_data.interface_id &&
obex_last_opcode_data->adapter_id == obex_proto_data.adapter_id &&
obex_last_opcode_data->chandle == obex_proto_data.chandle &&
obex_last_opcode_data->channel == obex_proto_data.channel) {
if (obex_last_opcode_data->request_in_frame > 0 && obex_last_opcode_data->request_in_frame != pinfo->fd->num) {
sub_item = proto_tree_add_uint(main_tree, hf_request_in_frame, next_tvb, 0, 0, obex_last_opcode_data->request_in_frame);
PROTO_ITEM_SET_GENERATED(sub_item);
@ -2690,18 +2581,18 @@ dissect_btobex(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
offset += 2;
if (!pinfo->fd->flags.visited)
save_path(pinfo, path, "", FALSE, is_obex_over_l2cap, data);
save_path(pinfo, path, "", FALSE, &obex_proto_data);
}
break;
}
dissect_headers(main_tree, next_tvb, offset, pinfo, profile, is_obex_over_l2cap, obex_last_opcode_data, data);
dissect_headers(main_tree, next_tvb, offset, pinfo, profile, obex_last_opcode_data, &obex_proto_data);
if (!pinfo->fd->flags.visited &&
obex_last_opcode_data &&
obex_last_opcode_data->data.set_data.name &&
obex_last_opcode_data->code == BTOBEX_CODE_VALS_SET_PATH &&
code == BTOBEX_CODE_VALS_SUCCESS) {
save_path(pinfo, path, obex_last_opcode_data->data.set_data.name, obex_last_opcode_data->data.set_data.go_up, is_obex_over_l2cap, data);
save_path(pinfo, path, obex_last_opcode_data->data.set_data.name, obex_last_opcode_data->data.set_data.go_up, &obex_proto_data);
}
} else {
/* packet fragment */

View File

@ -97,7 +97,7 @@ static int hf_address = -1;
static int hf_control = -1;
/* Initialize the protocol and registered fields */
static int proto_btrfcomm = -1;
int proto_btrfcomm = -1;
static int proto_btdun = -1;
static int proto_btspp = -1;
static int proto_btgnss = -1;

View File

@ -33,6 +33,8 @@ typedef struct _btrfcomm_data_t {
guint32 remote_bd_addr_id;
} btrfcomm_data_t;
extern int proto_btrfcomm;
#endif
/*

View File

@ -182,19 +182,23 @@ dissect_btsmp_key_dist(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree
static int
dissect_btsmp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
{
int offset = 0;
proto_item *ti;
proto_tree *st;
guint8 opcode;
btl2cap_data_t *l2cap_data;
guint32 interface_id;
guint32 adapter_id;
int offset = 0;
proto_item *ti;
proto_tree *st;
guint8 opcode;
guint32 interface_id;
guint32 adapter_id;
gint previous_proto;
l2cap_data = (btl2cap_data_t *) data;
previous_proto = (GPOINTER_TO_INT(wmem_list_frame_data(wmem_list_frame_prev(wmem_list_tail(pinfo->layers)))));
if (data && previous_proto == proto_btl2cap) {
btl2cap_data_t *l2cap_data;
if (l2cap_data) {
interface_id = l2cap_data->interface_id;
adapter_id = l2cap_data->adapter_id;
l2cap_data = (btl2cap_data_t *) data;
if (l2cap_data) {
interface_id = l2cap_data->interface_id;
adapter_id = l2cap_data->adapter_id;
}
} else {
interface_id = HCI_INTERFACE_DEFAULT;
adapter_id = HCI_ADAPTER_DEFAULT;