aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--epan/dissectors/packet-btavctp.c163
-rw-r--r--epan/dissectors/packet-btavctp.h7
-rw-r--r--epan/dissectors/packet-btavrcp.c339
-rw-r--r--epan/dissectors/packet-bthci_acl.c69
-rw-r--r--epan/dissectors/packet-btl2cap.c706
5 files changed, 990 insertions, 294 deletions
diff --git a/epan/dissectors/packet-btavctp.c b/epan/dissectors/packet-btavctp.c
index 20a1985bab..d31bbf4fad 100644
--- a/epan/dissectors/packet-btavctp.c
+++ b/epan/dissectors/packet-btavctp.c
@@ -60,6 +60,10 @@ typedef struct _fragment_t {
} fragment_t;
typedef struct _fragments_t {
+ guint32 interface_id;
+ guint32 adapter_id;
+ guint32 chandle;
+ guint32 psm;
guint32 count;
guint32 number_of_packets;
guint32 pid;
@@ -165,8 +169,11 @@ dissect_btavctp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
}
avctp_data = ep_alloc(sizeof(btavctp_data_t));
- avctp_data->cr = cr;
- avctp_data->psm = l2cap_data->psm;
+ 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;
save_private_data = pinfo->private_data;
pinfo->private_data = avctp_data;
@@ -185,8 +192,43 @@ dissect_btavctp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
else
call_dissector(data_handle, next_tvb, pinfo, tree);
} else {
+ emem_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;
+
+ 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;
+
+ 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_chandle;
+ key[3].length = 1;
+ key[3].key = &k_psm;
+ key[4].length = 1;
+ key[4].key = &k_frame_number;
+ key[5].length = 0;
+ key[5].key = NULL;
+
if (packet_type == PACKET_TYPE_START) {
- if(!pinfo->fd->flags.visited){
+ if (!pinfo->fd->flags.visited) {
fragment = se_alloc(sizeof(fragment_t));
fragment->length = length;
fragment->data = se_alloc(fragment->length);
@@ -200,29 +242,66 @@ dissect_btavctp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
fragments->fragment = se_tree_create(EMEM_TREE_TYPE_RED_BLACK, "btavctp fragments");
se_tree_insert32(fragments->fragment, fragments->count, fragment);
- se_tree_insert32(reassembling, pinfo->fd->num, fragments);
+ fragments->interface_id = interface_id;
+ fragments->adapter_id = adapter_id;
+ fragments->chandle = chandle;
+ fragments->psm = psm;
+
+ se_tree_insert32_array(reassembling, key, fragments);
} else {
- fragments = se_tree_lookup32_le(reassembling, pinfo->fd->num);
+ fragments = se_tree_lookup32_array_le(reassembling, key);
+ if (!(fragments && fragments->interface_id == interface_id &&
+ fragments->adapter_id == adapter_id &&
+ fragments->chandle == chandle &&
+ fragments->psm == psm))
+ fragments = NULL;
}
call_dissector(data_handle, next_tvb, pinfo, tree);
} else if (packet_type == PACKET_TYPE_CONTINUE) {
- if(!pinfo->fd->flags.visited) {
- if (fragments != NULL) {
- fragment = se_alloc(sizeof(fragment_t));
- fragment->length = length;
- fragment->data = se_alloc(fragment->length);
- tvb_memcpy(tvb, fragment->data, offset, fragment->length);
+ fragments = se_tree_lookup32_array_le(reassembling, key);
+ if (!(fragments && fragments->interface_id == interface_id &&
+ fragments->adapter_id == adapter_id &&
+ fragments->chandle == chandle &&
+ fragments->psm == psm))
+ fragments = NULL;
+
+ if (!pinfo->fd->flags.visited && fragments != NULL) {
+ fragment = se_alloc(sizeof(fragment_t));
+ fragment->length = length;
+ fragment->data = se_alloc(fragment->length);
+ tvb_memcpy(tvb, fragment->data, offset, fragment->length);
- fragments->count++;
- se_tree_insert32(fragments->fragment, fragments->count, fragment);
+ fragments->count++;
+ se_tree_insert32(fragments->fragment, fragments->count, fragment);
- se_tree_insert32(reassembling, pinfo->fd->num, fragments);
- }
- } else {
- fragments = se_tree_lookup32_le(reassembling, pinfo->fd->num);
+ fragments->interface_id = interface_id;
+ fragments->adapter_id = adapter_id;
+ 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;
+
+ 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_chandle;
+ key[3].length = 1;
+ key[3].key = &k_psm;
+ key[4].length = 1;
+ key[4].key = &k_frame_number;
+ key[5].length = 0;
+ key[5].key = NULL;
+
+ se_tree_insert32_array(reassembling, key, fragments);
}
call_dissector(data_handle, next_tvb, pinfo, tree);
@@ -231,21 +310,47 @@ dissect_btavctp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
guint i_length = 0;
guint8 *reassembled;
- if(!pinfo->fd->flags.visited){
+ fragments = se_tree_lookup32_array_le(reassembling, key);
+ if (!(fragments && fragments->interface_id == interface_id &&
+ fragments->adapter_id == adapter_id &&
+ fragments->chandle == chandle &&
+ fragments->psm == psm))
+ fragments = NULL;
- if (fragments != NULL) {
- fragment = se_alloc(sizeof(fragment_t));
- fragment->length = length;
- fragment->data = se_alloc(fragment->length);
- tvb_memcpy(tvb, fragment->data, offset, fragment->length);
+ if (!pinfo->fd->flags.visited && fragments != NULL) {
+ fragment = se_alloc(sizeof(fragment_t));
+ fragment->length = length;
+ fragment->data = se_alloc(fragment->length);
+ tvb_memcpy(tvb, fragment->data, offset, fragment->length);
- fragments->count++;
- se_tree_insert32(fragments->fragment, fragments->count, fragment);
+ fragments->count++;
+ se_tree_insert32(fragments->fragment, fragments->count, fragment);
- se_tree_insert32(reassembling, pinfo->fd->num, fragments);
- }
- } else {
- fragments = se_tree_lookup32_le(reassembling, pinfo->fd->num);
+ fragments->interface_id = interface_id;
+ fragments->adapter_id = adapter_id;
+ fragments->chandle = chandle;
+ fragments->psm = psm;
+
+ 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_chandle;
+ key[3].length = 1;
+ key[3].key = &k_psm;
+ key[4].length = 1;
+ key[4].key = &k_frame_number;
+ key[5].length = 0;
+ key[5].key = NULL;
+
+ k_interface_id = interface_id;
+ k_adapter_id = adapter_id;
+ k_chandle = chandle;
+ k_psm = psm;
+ k_frame_number = pinfo->fd->num;
+
+ se_tree_insert32_array(reassembling, key, fragments);
}
length = 0;
diff --git a/epan/dissectors/packet-btavctp.h b/epan/dissectors/packet-btavctp.h
index 1a25b66e69..38d078a4c1 100644
--- a/epan/dissectors/packet-btavctp.h
+++ b/epan/dissectors/packet-btavctp.h
@@ -28,8 +28,11 @@
#define __PACKET_BTAVCTP_H__
typedef struct _btavctp_data_t {
- guint8 cr;
- guint16 psm;
+ guint32 interface_id;
+ guint32 adapter_id;
+ guint16 chandle; /* only low 12 bits used */
+ guint16 psm;
+ guint8 cr;
} btavctp_data_t;
#endif
diff --git a/epan/dissectors/packet-btavrcp.c b/epan/dissectors/packet-btavrcp.c
index d1b45d4929..f5d1a3c883 100644
--- a/epan/dissectors/packet-btavrcp.c
+++ b/epan/dissectors/packet-btavrcp.c
@@ -262,7 +262,11 @@ static emem_tree_t *timing = NULL;
typedef struct _fragment {
guint start_frame_number;
guint end_frame_number;
- guint op;
+ guint32 interface_id;
+ guint32 adapter_id;
+ guint32 chandle;
+ guint32 psm;
+ guint32 op;
guint state;
guint32 count;
emem_tree_t *fragments;
@@ -280,8 +284,12 @@ typedef struct _timing_info {
nstime_t response_timestamp;
guint max_response_time;
guint used;
- guint opcode;
- guint op;
+ guint32 interface_id;
+ guint32 adapter_id;
+ guint32 chandle;
+ guint32 psm;
+ guint32 opcode;
+ guint32 op;
} timing_info_t;
static const value_string packet_type_vals[] = {
@@ -981,7 +989,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, guint *op,
+ gint offset, guint ctype, guint32 *op,
gboolean is_command)
{
guint pdu_id;
@@ -990,6 +998,25 @@ dissect_vendor_dependant(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
guint packet_type;
guint parameter_length;
guint length;
+ emem_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;
+ btavctp_data_t *avctp_data;
+
+ avctp_data = (btavctp_data_t *) pinfo->private_data;
+
+ 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);
@@ -1037,17 +1064,17 @@ dissect_vendor_dependant(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
if (pinfo->fd->flags.visited == 0) {
fragment_t *fragment;
data_fragment_t *data_fragment;
- emem_tree_key_t key[3];
- guint32 f_op;
- guint32 f_frame_number;
- f_op = pdu_id | (company_id << 8);
- f_frame_number = pinfo->fd->num;
+ 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;
fragment = se_alloc(sizeof(fragment_t));
fragment->start_frame_number = pinfo->fd->num;
fragment->end_frame_number = 0;
- fragment->op = pdu_id | (company_id << 8);
fragment->state = 0;
fragment->count = 1;
@@ -1061,11 +1088,25 @@ dissect_vendor_dependant(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
se_tree_insert32(fragment->fragments, fragment->count, data_fragment);
key[0].length = 1;
- key[0].key = &f_op;
+ key[0].key = &k_interface_id;
key[1].length = 1;
- key[1].key = &f_frame_number;
- key[2].length = 0;
- key[2].key = NULL;
+ key[1].key = &k_adapter_id;
+ key[2].length = 1;
+ key[2].key = &k_chandle;
+ key[3].length = 1;
+ key[3].key = &k_psm;
+ key[4].length = 1;
+ key[4].key = &k_op;
+ key[5].length = 1;
+ key[5].key = &k_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->op = pdu_id | (company_id << 8);
se_tree_insert32_array(reassembling, key, fragment);
}
@@ -1076,22 +1117,36 @@ dissect_vendor_dependant(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
if (pinfo->fd->flags.visited == 0) {
fragment_t *fragment;
data_fragment_t *data_fragment;
- emem_tree_key_t key[3];
- guint32 f_op;
- guint32 f_frame_number;
- f_op = pdu_id | (company_id << 8);
- f_frame_number = pinfo->fd->num;
+ 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;
key[0].length = 1;
- key[0].key = &f_op;
+ key[0].key = &k_interface_id;
key[1].length = 1;
- key[1].key = &f_frame_number;
- key[2].length = 0;
- key[2].key = NULL;
+ key[1].key = &k_adapter_id;
+ key[2].length = 1;
+ key[2].key = &k_chandle;
+ key[3].length = 1;
+ key[3].key = &k_psm;
+ key[4].length = 1;
+ key[4].key = &k_op;
+ key[5].length = 1;
+ key[5].key = &k_frame_number;
+ key[6].length = 0;
+ key[6].key = NULL;
fragment = se_tree_lookup32_array_le(reassembling, key);
- if (fragment && fragment->op == (pdu_id | (company_id << 8)) && fragment->state == 1) {
+ if (fragment && fragment->interface_id == interface_id &&
+ fragment->adapter_id == adapter_id &&
+ fragment->chandle == chandle &&
+ fragment->psm == psm &&
+ fragment->op == (pdu_id | (company_id << 8)) &&
+ fragment->state == 1) {
fragment->count += 1;
fragment->state = 0;
@@ -1108,9 +1163,6 @@ dissect_vendor_dependant(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
} else if (packet_type == PACKET_TYPE_END) {
fragment_t *fragment;
data_fragment_t *data_fragment;
- emem_tree_key_t key[3];
- guint32 f_op;
- guint32 f_frame_number;
guint i_frame;
tvbuff_t *next_tvb;
guint i_length = 0;
@@ -1118,18 +1170,34 @@ dissect_vendor_dependant(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
col_append_fstr(pinfo->cinfo, COL_INFO, " [end]");
- f_op = pdu_id | (company_id << 8);
- f_frame_number = pinfo->fd->num;
+ 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;
key[0].length = 1;
- key[0].key = &f_op;
+ key[0].key = &k_interface_id;
key[1].length = 1;
- key[1].key = &f_frame_number;
- key[2].length = 0;
- key[2].key = NULL;
+ key[1].key = &k_adapter_id;
+ key[2].length = 1;
+ key[2].key = &k_chandle;
+ key[3].length = 1;
+ key[3].key = &k_psm;
+ key[4].length = 1;
+ key[4].key = &k_op;
+ key[5].length = 1;
+ key[5].key = &k_frame_number;
+ key[6].length = 0;
+ key[6].key = NULL;
fragment = se_tree_lookup32_array_le(reassembling, key);
- if (fragment && fragment->op == (pdu_id | (company_id << 8))) {
+ if (fragment && fragment->interface_id == interface_id &&
+ fragment->adapter_id == adapter_id &&
+ fragment->chandle == chandle &&
+ fragment->psm == psm &&
+ fragment->op == (pdu_id | (company_id << 8))) {
if (fragment->state == 1 && pinfo->fd->flags.visited == 0) {
fragment->end_frame_number = pinfo->fd->num;
fragment->count += 1;
@@ -1600,22 +1668,36 @@ dissect_vendor_dependant(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
if (pinfo->fd->flags.visited == 0) {
fragment_t *fragment;
- emem_tree_key_t key[3];
- guint32 f_op;
- guint32 f_frame_number;
- f_op = continuing_op;
- f_frame_number = pinfo->fd->num;
+ 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;
key[0].length = 1;
- key[0].key = &f_op;
+ key[0].key = &k_interface_id;
key[1].length = 1;
- key[1].key = &f_frame_number;
- key[2].length = 0;
- key[2].key = NULL;
+ key[1].key = &k_adapter_id;
+ key[2].length = 1;
+ key[2].key = &k_chandle;
+ key[3].length = 1;
+ key[3].key = &k_psm;
+ key[4].length = 1;
+ key[4].key = &k_op;
+ key[5].length = 1;
+ key[5].key = &k_frame_number;
+ key[6].length = 0;
+ key[6].key = NULL;
fragment = se_tree_lookup32_array_le(reassembling, key);
- if (fragment && fragment->op == continuing_op && fragment->state == 0) {
+ if (fragment && fragment->interface_id == interface_id &&
+ fragment->adapter_id == adapter_id &&
+ fragment->chandle == chandle &&
+ fragment->psm == psm &&
+ fragment->op == continuing_op &&
+ fragment->state == 0) {
fragment->state = 1;
}
}
@@ -1637,22 +1719,36 @@ dissect_vendor_dependant(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
if (pinfo->fd->flags.visited == 0) {
fragment_t *fragment;
- emem_tree_key_t key[3];
- guint32 f_op;
- guint32 f_frame_number;
- f_op = continuing_op;
- f_frame_number = pinfo->fd->num;
+ 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;
key[0].length = 1;
- key[0].key = &f_op;
+ key[0].key = &k_interface_id;
key[1].length = 1;
- key[1].key = &f_frame_number;
- key[2].length = 0;
- key[2].key = NULL;
+ key[1].key = &k_adapter_id;
+ key[2].length = 1;
+ key[2].key = &k_chandle;
+ key[3].length = 1;
+ key[3].key = &k_psm;
+ key[4].length = 1;
+ key[4].key = &k_op;
+ key[5].length = 1;
+ key[5].key = &k_frame_number;
+ key[6].length = 0;
+ key[6].key = NULL;
fragment = se_tree_lookup32_array_le(reassembling, key);
- if (fragment && fragment->op == continuing_op && fragment->state == 0) {
+ if (fragment && fragment->interface_id == interface_id &&
+ fragment->adapter_id == adapter_id &&
+ fragment->chandle == chandle &&
+ fragment->psm == psm &&
+ fragment->op == continuing_op &&
+ fragment->state == 0) {
fragment->state = 3;
}
}
@@ -2000,17 +2096,25 @@ dissect_btavrcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
proto_tree *btavrcp_tree;
proto_item *pitem = NULL;
gint offset = 0;
- guint opcode;
- guint op = 0;
+ guint32 opcode;
+ guint32 op = 0;
guint ctype;
guint response_time;
guint max_response_time;
guint is_command;
timing_info_t *timing_info;
- emem_tree_key_t t_key[4];
- guint32 t_opcode;
- guint32 t_op;
- guint32 t_frame_number;
+ emem_tree_key_t key[8];
+ guint32 k_interface_id;
+ guint32 k_adapter_id;
+ guint32 k_chandle;
+ guint32 k_psm;
+ guint32 k_opcode;
+ guint32 k_op;
+ guint32 k_frame_number;
+ guint32 interface_id;
+ guint32 adapter_id;
+ guint32 chandle;
+ guint32 psm;
btavctp_data_t *avctp_data;
avctp_data = (btavctp_data_t *) pinfo->private_data;
@@ -2043,6 +2147,11 @@ dissect_btavrcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
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_CTRL) {
proto_tree_add_item(btavrcp_tree, hf_btavrcp_reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
proto_tree_add_item(btavrcp_tree, hf_btavrcp_ctype, tvb, offset, 1, ENC_BIG_ENDIAN);
@@ -2074,18 +2183,30 @@ dissect_btavrcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
break;
};
- t_opcode = opcode;
- t_op = op;
- t_frame_number = pinfo->fd->num;
+ k_interface_id = interface_id;
+ k_adapter_id = adapter_id;
+ k_chandle = chandle;
+ k_psm = psm;
+ k_opcode = opcode;
+ k_op = op;
+ k_frame_number = pinfo->fd->num;
- t_key[0].length = 1;
- t_key[0].key = &t_opcode;
- t_key[1].length = 1;
- t_key[1].key = &t_op;
- t_key[2].length = 1;
- t_key[2].key = &t_frame_number;
- t_key[3].length = 0;
- t_key[3].key = NULL;
+ 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_chandle;
+ key[3].length = 1;
+ key[3].key = &k_psm;
+ key[4].length = 1;
+ key[4].key = &k_opcode;
+ key[5].length = 1;
+ key[5].key = &k_op;
+ key[6].length = 1;
+ key[6].key = &k_frame_number;
+ key[7].length = 0;
+ key[7].key = NULL;
if (pinfo->fd->flags.visited == 0) {
if (is_command) {
@@ -2106,35 +2227,73 @@ dissect_btavrcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
timing_info->response_timestamp.nsecs = 0;
timing_info->max_response_time = max_response_time;
- timing_info->opcode = opcode;
- timing_info->op = op;
- timing_info->used = 0;
+ timing_info->interface_id = interface_id;
+ timing_info->adapter_id = adapter_id;
+ timing_info->chandle = chandle;
+ timing_info->psm = psm;
+ timing_info->opcode = opcode;
+ timing_info->op = op;
+ timing_info->used = 0;
- se_tree_insert32_array(timing, t_key, timing_info);
+ se_tree_insert32_array(timing, key, timing_info);
} else {
- timing_info = se_tree_lookup32_array_le(timing, t_key);
- if (timing_info && timing_info->opcode == opcode && timing_info->op == op && timing_info->used == 0) {
+ timing_info = se_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 &&
+ timing_info->opcode == opcode &&
+ timing_info->op == op &&
+ timing_info->used == 0) {
timing_info->response_frame_number = pinfo->fd->num;
timing_info->response_timestamp = pinfo->fd->abs_ts;
timing_info->used = 1;
}
}
- t_key[0].length = 1;
- t_key[0].key = &t_opcode;
- t_key[1].length = 1;
- t_key[1].key = &t_op;
- t_key[2].length = 1;
- t_key[2].key = &t_frame_number;
- t_key[3].length = 0;
- t_key[3].key = NULL;
+ k_interface_id = interface_id;
+ k_adapter_id = adapter_id;
+ k_chandle = chandle;
+ k_psm = psm;
+ k_opcode = opcode;
+ k_op = op;
+ 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_chandle;
+ key[3].length = 1;
+ key[3].key = &k_psm;
+ key[4].length = 1;
+ key[4].key = &k_opcode;
+ key[5].length = 1;
+ key[5].key = &k_op;
+ key[6].length = 1;
+ key[6].key = &k_frame_number;
+ key[7].length = 0;
+ key[7].key = NULL;
}
- timing_info = se_tree_lookup32_array_le(timing, t_key);
- if (timing_info && timing_info->opcode == opcode && timing_info->op == op) {
- response_time = timing_info->response_timestamp.nsecs - timing_info->command_timestamp.nsecs;
- response_time /= 1000000;
- response_time += ((guint)timing_info->response_timestamp.secs - (guint)timing_info->command_timestamp.secs) / 1000;
+ timing_info = se_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 &&
+ timing_info->opcode == opcode &&
+ timing_info->op == op) {
+
+ if (timing_info->command_timestamp.nsecs > timing_info->response_timestamp.nsecs) {
+ response_time = timing_info->response_timestamp.nsecs + (1000000000 - timing_info->command_timestamp.nsecs);
+ response_time /= 1000000;
+ response_time += ((guint)timing_info->response_timestamp.secs - 1 - (guint)timing_info->command_timestamp.secs) / 1000;
+ } else {
+ response_time = timing_info->response_timestamp.nsecs - timing_info->command_timestamp.nsecs;
+ response_time /= 1000000;
+ response_time += ((guint)timing_info->response_timestamp.secs - (guint)timing_info->command_timestamp.secs) / 1000;
+ }
if (timing_info->response_frame_number == 0) {
response_time = UINT_MAX;
diff --git a/epan/dissectors/packet-bthci_acl.c b/epan/dissectors/packet-bthci_acl.c
index cdd8aeb56e..e405307201 100644
--- a/epan/dissectors/packet-bthci_acl.c
+++ b/epan/dissectors/packet-bthci_acl.c
@@ -65,6 +65,9 @@ typedef struct _multi_fragment_pdu_t {
typedef struct _chandle_data_t {
emem_tree_t *start_fragments; /* indexed by pinfo->fd->num */
+ guint32 interface_id;
+ guint32 adapter_id;
+ guint32 chandle;
} chandle_data_t;
static emem_tree_t *chandle_tree = NULL;
@@ -156,8 +159,8 @@ dissect_bthci_acl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
/* remote bdaddr and name */
remote_bdaddr = se_tree_lookup32_array_le(hci_data->chandle_to_bdaddr_table, key);
- if (remote_bdaddr && remote_bdaddr->interface_id == k_interface_id &&
- remote_bdaddr->adapter_id == k_adapter_id &&
+ if (remote_bdaddr && remote_bdaddr->interface_id == hci_data->interface_id &&
+ remote_bdaddr->adapter_id == hci_data->adapter_id &&
remote_bdaddr->chandle == (flags & 0x0fff)) {
guint32 k_bd_addr_oui;
guint32 k_bd_addr_id;
@@ -171,8 +174,10 @@ dissect_bthci_acl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
bd_addr_oui = remote_bdaddr->bd_addr[0] << 16 | remote_bdaddr->bd_addr[1] << 8 | remote_bdaddr->bd_addr[2];
bd_addr_id = remote_bdaddr->bd_addr[3] << 16 | remote_bdaddr->bd_addr[4] << 8 | remote_bdaddr->bd_addr[5];
- k_bd_addr_oui = bd_addr_oui;
- k_bd_addr_id = bd_addr_id;
+
+ k_bd_addr_oui = bd_addr_oui;
+ k_bd_addr_id = bd_addr_id;
+ k_frame_number = pinfo->fd->num;
key[0].length = 1;
key[0].key = &k_bd_addr_id;
@@ -216,6 +221,10 @@ dissect_bthci_acl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
}
}
+ k_interface_id = hci_data->interface_id;
+ k_adapter_id = hci_data->adapter_id;
+ k_frame_number = pinfo->fd->num;
+
/* localhost bdaddr and name */
key[0].length = 1;
key[0].key = &k_interface_id;
@@ -228,15 +237,15 @@ dissect_bthci_acl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
localhost_bdaddr_entry = se_tree_lookup32_array_le(hci_data->localhost_bdaddr, key);
- if (localhost_bdaddr_entry && localhost_bdaddr_entry->interface_id == k_interface_id &&
- localhost_bdaddr_entry->adapter_id == k_adapter_id)
+ if (localhost_bdaddr_entry && localhost_bdaddr_entry->interface_id == hci_data->interface_id &&
+ localhost_bdaddr_entry->adapter_id == hci_data->adapter_id)
localhost_ether_addr = get_ether_name(localhost_bdaddr_entry->bd_addr);
else
localhost_ether_addr = "localhost";
localhost_name_entry = se_tree_lookup32_array_le(hci_data->localhost_name, key);
- if (localhost_name_entry && localhost_name_entry->interface_id == k_interface_id &&
- localhost_name_entry->adapter_id == k_adapter_id)
+ if (localhost_name_entry && localhost_name_entry->interface_id == hci_data->interface_id &&
+ localhost_name_entry->adapter_id == hci_data->adapter_id)
localhost_name = localhost_name_entry->name;
else
localhost_name = "";
@@ -257,11 +266,49 @@ dissect_bthci_acl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
}
/* find the chandle_data structure associated with this chandle */
- chandle_data = se_tree_lookup32(chandle_tree, acl_data->chandle);
- if (!chandle_data) {
+ k_interface_id = hci_data->interface_id;
+ k_adapter_id = hci_data->adapter_id;
+ k_connection_handle = flags & 0x0fff;
+ 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_connection_handle;
+ key[3].length = 1;
+ key[3].key = &k_frame_number;
+ key[4].length = 0;
+ key[4].key = NULL;
+
+ chandle_data = se_tree_lookup32_array_le(chandle_tree, key);
+ if (!(chandle_data && chandle_data->interface_id == hci_data->interface_id &&
+ chandle_data->adapter_id == hci_data->adapter_id &&
+ chandle_data->chandle == (flags & 0x0fff))) {
+ k_interface_id = hci_data->interface_id;
+ k_adapter_id = hci_data->adapter_id;
+ k_connection_handle = flags & 0x0fff;
+ 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_connection_handle;
+ key[3].length = 1;
+ key[3].key = &k_frame_number;
+ key[4].length = 0;
+ key[4].key = NULL;
+
chandle_data = se_alloc(sizeof(chandle_data_t));
chandle_data->start_fragments = se_tree_create_non_persistent(EMEM_TREE_TYPE_RED_BLACK, "bthci_acl fragment starts");
- se_tree_insert32(chandle_tree, acl_data->chandle, chandle_data);
+ chandle_data->interface_id = hci_data->interface_id;
+ chandle_data->adapter_id = hci_data->adapter_id;
+ chandle_data->chandle = flags & 0x0fff;
+
+ se_tree_insert32_array(chandle_tree, key, chandle_data);
}
length = tvb_get_letohs(tvb, offset);
diff --git a/epan/dissectors/packet-btl2cap.c b/epan/dissectors/packet-btl2cap.c
index 20e154c8d9..1cdc361e36 100644
--- a/epan/dissectors/packet-btl2cap.c
+++ b/epan/dissectors/packet-btl2cap.c
@@ -141,8 +141,7 @@ static dissector_table_t l2cap_service_dissector_table;
/* This table maps cid values to psm values.
* The same table is used both for SCID and DCID.
- * For received CIDs we 'or' the cid with 0x8000 in this table
- * Table is indexed by array: CID and frame number which created CID
+ * For received CIDs we 'or' the cid with 0x80000000 in this table
*/
static emem_tree_t *cid_to_psm_table = NULL;
static emem_tree_t *psm_to_service_table = NULL;
@@ -153,9 +152,22 @@ typedef struct _config_data_t {
emem_tree_t *start_fragments; /* indexed by pinfo->fd->num */
} config_data_t;
+typedef struct _sdu_reassembly_t
+{
+ guint8 *reassembled;
+ guint8 seq;
+ guint32 first_frame;
+ guint32 last_frame;
+ guint16 tot_len;
+ int cur_off; /* counter used by reassembly */
+} sdu_reassembly_t;
+
typedef struct _psm_data_t {
- guint16 scid;
- guint16 dcid;
+ guint32 interface_id;
+ guint32 adapter_id;
+ guint32 chandle;
+ guint32 scid;
+ guint32 dcid;
guint32 first_scid_frame;
guint32 first_dcid_frame;
guint16 psm;
@@ -164,6 +176,15 @@ typedef struct _psm_data_t {
config_data_t out;
} psm_data_t;
+typedef struct _psm_service_t {
+ guint32 interface_id;
+ guint32 adapter_id;
+ guint32 chandle;
+ guint32 psm;
+ guint32 service;
+} psm_service_t;
+
+
static const value_string command_code_vals[] = {
{ 0x01, "Command Reject" },
{ 0x02, "Connection Request" },
@@ -336,6 +357,21 @@ static const value_string ctrl_id_code_vals[] = {
{ 0, NULL }
};
+static const range_string cid_rvals[] = {
+ { 0x0000, 0x0000, "Null identifier" },
+ { 0x0001, 0x0001, "L2CAP Signaling Channel" },
+ { 0x0002, 0x0002, "Connectionless Channel" },
+ { 0x0003, 0x0003, "AMP Manager Protocol" },
+ { 0x0004, 0x0004, "Attribute Protocol" },
+ { 0x0005, 0x0005, "Low Energy L2CAP Signaling Channel" },
+ { 0x0006, 0x0006, "Security Manager Protocol" },
+ { 0x0007, 0x003E, "Reserved" },
+ { 0x003F, 0x003F, "AMP Test Manager" },
+ { 0x0040, 0xFFFF, "Dynamically Allocated Channel" },
+ { 0, 0, NULL }
+};
+
+
static int
dissect_comrej(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree)
{
@@ -373,26 +409,65 @@ dissect_comrej(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tr
static int
dissect_connrequest(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, gboolean is_ch_request)
{
- guint16 scid, psm;
- psm_data_t *psm_data;
- const gchar *psm_str = "<NONE>";
+ guint16 scid;
+ guint16 psm;
+ emem_tree_key_t key[6];
+ guint32 k_interface_id;
+ guint32 k_adapter_id;
+ guint32 k_chandle;
+ guint32 k_cid;
+ guint32 k_psm;
+ guint32 k_frame_number;
+ guint32 interface_id;
+ guint32 adapter_id;
+ guint32 chandle;
+ guint32 key_psm;
+ bthci_acl_data_t *acl_data = (bthci_acl_data_t *) pinfo->private_data;
+ psm_data_t *psm_data;
+ const gchar *psm_str = "<NONE>";
psm = tvb_get_letohs(tvb, offset);
+
+ interface_id = (acl_data) ? acl_data->interface_id : HCI_INTERFACE_AMP;
+ adapter_id = (acl_data) ? acl_data->adapter_id : HCI_ADAPTER_DEFAULT;
+ chandle = (acl_data) ? acl_data->chandle : 0;
+ key_psm = psm | ((pinfo->p2p_dir == P2P_DIR_RECV) ? 0x80000000 : 0x00000000);
+
if (psm < BTL2CAP_DYNAMIC_PSM_START) {
proto_tree_add_item(tree, hf_btl2cap_psm, tvb, offset, 2, ENC_LITTLE_ENDIAN);
psm_str = val_to_str_const(psm, psm_vals, "Unknown PSM");
- }
- else {
- guint32 *service, token;
- proto_item *item;
+ } else {
+ psm_service_t *psm_service;
+ proto_item *item;
item = proto_tree_add_item(tree, hf_btl2cap_psm_dynamic, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- token = psm | ((pinfo->p2p_dir == P2P_DIR_RECV)?0x80000000:0x00000000);
- service = se_tree_lookup32(psm_to_service_table, token);
- if (service) {
- psm_str = val_to_str_ext_const(*service, &vs_service_classes_ext, "Unknown PSM");
- proto_item_append_text(item," (%s)", psm_str);
+ k_interface_id = interface_id;
+ k_adapter_id = adapter_id;
+ k_chandle = chandle;
+ k_psm = key_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_chandle;
+ key[3].length = 1;
+ key[3].key = &k_psm;
+ key[4].length = 1;
+ key[4].key = &k_frame_number;
+ key[5].length = 0;
+ key[5].key = NULL;
+
+ psm_service = se_tree_lookup32_array_le(psm_to_service_table, key);
+ if (psm_service && psm_service->interface_id == interface_id &&
+ psm_service->adapter_id == adapter_id &&
+ psm_service->chandle == chandle &&
+ psm_service->psm == key_psm) {
+ psm_str = val_to_str_ext_const(psm_service->service, &vs_service_classes_ext, "Unknown PSM");
+ proto_item_append_text(item, " (%s)", psm_str);
}
}
offset += 2;
@@ -412,13 +487,14 @@ dissect_connrequest(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *t
}
if (!pinfo->fd->flags.visited) {
- emem_tree_key_t key[3];
- guint32 kcid;
- guint32 frame_number;
+ k_interface_id = interface_id;
+ k_adapter_id = adapter_id;
+ k_chandle = chandle;
+ k_cid = scid | ((pinfo->p2p_dir == P2P_DIR_RECV) ? 0x80000000 : 0x00000000);
+ k_frame_number = pinfo->fd->num;
- /* XXX: Is using 0x8000 OK ? scid appears to be 16 bits */
psm_data = se_alloc(sizeof(psm_data_t));
- psm_data->scid = (scid | ((pinfo->p2p_dir == P2P_DIR_RECV) ? 0x8000 : 0x0000));
+ psm_data->scid = (scid | ((pinfo->p2p_dir == P2P_DIR_RECV) ? 0x80000000 : 0x00000000));
psm_data->dcid = 0;
psm_data->psm = psm;
psm_data->first_scid_frame = 0;
@@ -430,16 +506,22 @@ dissect_connrequest(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *t
psm_data->out.mode = 0;
psm_data->out.txwindow = 0;
psm_data->out.start_fragments = se_tree_create_non_persistent(EMEM_TREE_TYPE_RED_BLACK, "bthci_l2cap fragment starts");
-
- frame_number = pinfo->fd->num;
- kcid = scid | ((pinfo->p2p_dir == P2P_DIR_RECV) ? 0x8000 : 0x0000);
+ psm_data->interface_id = k_interface_id;
+ psm_data->adapter_id = k_adapter_id;
+ psm_data->chandle = k_chandle;
key[0].length = 1;
- key[0].key = &kcid;
+ key[0].key = &k_interface_id;
key[1].length = 1;
- key[1].key = &frame_number;
- key[2].length = 0;
- key[2].key = NULL;
+ key[1].key = &k_adapter_id;
+ key[2].length = 1;
+ key[2].key = &k_chandle;
+ key[3].length = 1;
+ key[3].key = &k_cid;
+ key[4].length = 1;
+ key[4].key = &k_frame_number;
+ key[5].length = 0;
+ key[5].key = NULL;
se_tree_insert32_array(cid_to_psm_table, key, psm_data);
}
@@ -475,7 +557,7 @@ dissect_options(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *t
while (length > 0) {
option_type = tvb_get_guint8(tvb, offset);
- option_length = tvb_get_guint8(tvb, offset+1);
+ option_length = tvb_get_guint8(tvb, offset + 1);
ti_option = proto_tree_add_none_format(tree,
hf_btl2cap_option, tvb,
@@ -483,7 +565,7 @@ dissect_options(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *t
"Option: ");
ti_option_subtree = proto_item_add_subtree(ti_option, ett_btl2cap_option);
proto_tree_add_item(ti_option_subtree, hf_btl2cap_option_type, tvb, offset, 1, ENC_LITTLE_ENDIAN);
- proto_tree_add_item(ti_option_subtree, hf_btl2cap_option_length, tvb, offset+1, 1, ENC_LITTLE_ENDIAN);
+ proto_tree_add_item(ti_option_subtree, hf_btl2cap_option_length, tvb, offset + 1, 1, ENC_LITTLE_ENDIAN);
offset += 2;
if (option_length != 0) {
@@ -531,7 +613,7 @@ dissect_options(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *t
if (config_data)
{
config_data->mode = tvb_get_guint8(tvb, offset);
- config_data->txwindow = tvb_get_guint8(tvb, offset+1);
+ config_data->txwindow = tvb_get_guint8(tvb, offset + 1);
}
proto_tree_add_item(ti_option_subtree, hf_btl2cap_option_retransmissionmode, tvb, offset, 1, ENC_LITTLE_ENDIAN);
offset += 1;
@@ -606,27 +688,23 @@ dissect_options(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *t
static int
dissect_configrequest(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, guint16 length)
{
- psm_data_t *psm_data;
- config_data_t *config_data;
- guint16 dcid;
- emem_tree_key_t key[3];
- guint32 kcid;
- guint32 frame_number;
+ psm_data_t *psm_data;
+ config_data_t *config_data;
+ guint16 dcid;
+ emem_tree_key_t key[6];
+ guint32 k_interface_id;
+ guint32 k_adapter_id;
+ guint32 k_chandle;
+ guint32 k_cid;
+ guint32 k_frame_number;
+ guint32 interface_id;
+ guint32 adapter_id;
+ guint32 chandle;
+ guint32 cid;
+ bthci_acl_data_t *acl_data = (bthci_acl_data_t *) pinfo->private_data;
dcid = tvb_get_letohs(tvb, offset);
- frame_number = pinfo->fd->num;
- kcid = dcid | ((pinfo->p2p_dir == P2P_DIR_RECV) ? 0x0000 : 0x8000);
-
- key[0].length = 1;
- key[0].key = &kcid;
- key[1].length = 1;
- key[1].key = &frame_number;
- key[2].length = 0;
- key[2].key = NULL;
-
- psm_data = se_tree_lookup32_array_le(cid_to_psm_table, key);
-
proto_tree_add_item(tree, hf_btl2cap_dcid, tvb, offset, 2, ENC_LITTLE_ENDIAN);
offset += 2;
@@ -636,13 +714,42 @@ dissect_configrequest(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_t
offset += 2;
if (tvb_reported_length_remaining(tvb, offset) > 0) {
- if (psm_data && psm_data->dcid == (dcid | ((pinfo->p2p_dir == P2P_DIR_RECV) ? 0x0000 : 0x8000)))
+ interface_id = (acl_data) ? acl_data->interface_id : HCI_INTERFACE_AMP;
+ adapter_id = (acl_data) ? acl_data->adapter_id : HCI_ADAPTER_DEFAULT;
+ chandle = (acl_data) ? acl_data->chandle : 0;
+ cid = dcid | ((pinfo->p2p_dir == P2P_DIR_RECV) ? 0x00000000 : 0x80000000);
+
+ k_interface_id = interface_id;
+ k_adapter_id = adapter_id;
+ k_chandle = chandle;
+ k_cid = cid;
+ 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_chandle;
+ key[3].length = 1;
+ key[3].key = &k_cid;
+ key[4].length = 1;
+ key[4].key = &k_frame_number;
+ key[5].length = 0;
+ key[5].key = NULL;
+
+ psm_data = se_tree_lookup32_array_le(cid_to_psm_table, key);
+ if (psm_data && psm_data->interface_id == interface_id &&
+ psm_data->adapter_id == adapter_id &&
+ psm_data->chandle == chandle &&
+ psm_data->dcid == (dcid | ((pinfo->p2p_dir == P2P_DIR_RECV) ? 0x00000000 : 0x80000000))) {
if (pinfo->p2p_dir == P2P_DIR_RECV)
config_data = &(psm_data->out);
else
config_data = &(psm_data->in);
- else
+ } else {
config_data = NULL;
+ }
offset = dissect_options(tvb, offset, pinfo, tree, length - 4, config_data);
}
@@ -762,27 +869,24 @@ dissect_inforesponse(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tr
static int
dissect_configresponse(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, guint16 length)
{
- psm_data_t *psm_data;
- config_data_t *config_data;
- guint16 scid, result;
- emem_tree_key_t key[3];
- guint32 kcid;
- guint32 frame_number;
+ psm_data_t *psm_data;
+ config_data_t *config_data;
+ guint16 scid;
+ guint16 result;
+ emem_tree_key_t key[6];
+ guint32 k_interface_id;
+ guint32 k_adapter_id;
+ guint32 k_chandle;
+ guint32 k_cid;
+ guint32 k_frame_number;
+ guint32 interface_id;
+ guint32 adapter_id;
+ guint32 chandle;
+ guint32 cid;
+ bthci_acl_data_t *acl_data = (bthci_acl_data_t *) pinfo->private_data;
scid = tvb_get_letohs(tvb, offset);
- frame_number = pinfo->fd->num;
- kcid = scid | ((pinfo->p2p_dir == P2P_DIR_RECV) ? 0x0000 : 0x8000);
-
- key[0].length = 1;
- key[0].key = &kcid;
- key[1].length = 1;
- key[1].key = &frame_number;
- key[2].length = 0;
- key[2].key = NULL;
-
- psm_data = se_tree_lookup32_array_le(cid_to_psm_table, key);
-
proto_tree_add_item(tree, hf_btl2cap_scid, tvb, offset, 2, ENC_LITTLE_ENDIAN);
offset += 2;
@@ -797,13 +901,42 @@ dissect_configresponse(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_
val_to_str_const(result, configuration_result_vals, "Unknown"), scid);
if (tvb_reported_length_remaining(tvb, offset) > 0) {
- if (psm_data && psm_data->scid == (scid | ((pinfo->p2p_dir == P2P_DIR_RECV) ? 0x0000 : 0x8000)))
+ interface_id = (acl_data) ? acl_data->interface_id : HCI_INTERFACE_AMP;
+ adapter_id = (acl_data) ? acl_data->adapter_id : HCI_ADAPTER_DEFAULT;
+ chandle = (acl_data) ? acl_data->chandle : 0;
+ cid = scid | ((pinfo->p2p_dir == P2P_DIR_RECV) ? 0x00000000 : 0x80000000);
+
+ k_interface_id = interface_id;
+ k_adapter_id = adapter_id;
+ k_chandle = chandle;
+ k_cid = cid;
+ 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_chandle;
+ key[3].length = 1;
+ key[3].key = &k_cid;
+ key[4].length = 1;
+ key[4].key = &k_frame_number;
+ key[5].length = 0;
+ key[5].key = NULL;
+
+ psm_data = se_tree_lookup32_array_le(cid_to_psm_table, key);
+ if (psm_data && psm_data->interface_id == interface_id &&
+ psm_data->adapter_id == adapter_id &&
+ psm_data->chandle == chandle &&
+ psm_data->scid == (scid | ((pinfo->p2p_dir == P2P_DIR_RECV) ? 0x00000000 : 0x80000000))) {
if (pinfo->p2p_dir == P2P_DIR_RECV)
config_data = &(psm_data->out);
else
config_data = &(psm_data->in);
- else
+ } else {
config_data = NULL;
+ }
offset = dissect_options(tvb, offset, pinfo, tree, length - 6, config_data);
}
@@ -813,11 +946,19 @@ dissect_configresponse(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_
static int
dissect_connresponse(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
{
- guint16 scid, dcid, result;
- psm_data_t *psm_data;
- emem_tree_key_t key[3];
- guint32 kcid;
- guint32 frame_number;
+ guint16 scid, dcid, result;
+ psm_data_t *psm_data;
+ emem_tree_key_t key[6];
+ guint32 k_interface_id;
+ guint32 k_adapter_id;
+ guint32 k_chandle;
+ guint32 k_cid;
+ guint32 k_frame_number;
+ guint32 interface_id;
+ guint32 adapter_id;
+ guint32 chandle;
+ guint32 cid;
+ bthci_acl_data_t *acl_data = (bthci_acl_data_t *) pinfo->private_data;
dcid = tvb_get_letohs(tvb, offset);
proto_tree_add_item(tree, hf_btl2cap_dcid, tvb, offset, 2, ENC_LITTLE_ENDIAN);
@@ -843,29 +984,57 @@ dissect_connresponse(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *
}
if (pinfo->fd->flags.visited == 0) {
- frame_number = pinfo->fd->num;
- kcid = scid | ((pinfo->p2p_dir == P2P_DIR_RECV) ? 0x0000 : 0x8000);
+ interface_id = (acl_data) ? acl_data->interface_id : HCI_INTERFACE_AMP;
+ adapter_id = (acl_data) ? acl_data->adapter_id : HCI_ADAPTER_DEFAULT;
+ chandle = (acl_data) ? acl_data->chandle : 0;
+ cid = scid | ((pinfo->p2p_dir == P2P_DIR_RECV) ? 0x00000000 : 0x80000000);
+
+ k_interface_id = interface_id;
+ k_adapter_id = adapter_id;
+ k_chandle = chandle;
+ k_cid = cid;
+ k_frame_number = pinfo->fd->num;
key[0].length = 1;
- key[0].key = &kcid;
+ key[0].key = &k_interface_id;
key[1].length = 1;
- key[1].key = &frame_number;
- key[2].length = 0;
- key[2].key = NULL;
+ key[1].key = &k_adapter_id;
+ key[2].length = 1;
+ key[2].key = &k_chandle;
+ key[3].length = 1;
+ key[3].key = &k_cid;
+ key[4].length = 1;
+ key[4].key = &k_frame_number;
+ key[5].length = 0;
+ key[5].key = NULL;
psm_data = se_tree_lookup32_array_le(cid_to_psm_table, key);
-
- if (psm_data && psm_data->scid == (scid | ((pinfo->p2p_dir == P2P_DIR_RECV) ? 0x0000 : 0x8000))) {
- frame_number = pinfo->fd->num;
- kcid = dcid | ((pinfo->p2p_dir == P2P_DIR_RECV) ? 0x8000 : 0x0000);
-
- key[0].length = 1;
- key[0].key = &kcid;
- key[1].length = 1;
- key[1].key = &frame_number;
- key[2].length = 0;
- key[2].key = NULL;
- psm_data->dcid = dcid | ((pinfo->p2p_dir == P2P_DIR_RECV) ? 0x8000 : 0x0000);
+ if (psm_data && psm_data->interface_id == interface_id &&
+ psm_data->adapter_id == adapter_id &&
+ psm_data->chandle == chandle &&
+ psm_data->scid == (scid | ((pinfo->p2p_dir == P2P_DIR_RECV) ? 0x00000000 : 0x80000000))) {
+ cid = dcid | ((pinfo->p2p_dir == P2P_DIR_RECV) ? 0x80000000 : 0x00000000);
+
+ k_interface_id = interface_id;
+ k_adapter_id = adapter_id;
+ k_chandle = chandle;
+ k_cid = cid;
+ 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_chandle;
+ key[3].length = 1;
+ key[3].key = &k_cid;
+ key[4].length = 1;
+ key[4].key = &k_frame_number;
+ key[5].length = 0;
+ key[5].key = NULL;
+
+ psm_data->dcid = cid;
se_tree_insert32_array(cid_to_psm_table, key, psm_data);
}
@@ -938,22 +1107,22 @@ dissect_connparamrequest(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, prot
guint16 max_interval, slave_latency;
item = proto_tree_add_item(tree, hf_btl2cap_min_interval, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- proto_item_append_text(item, " (%g msec)", tvb_get_letohs(tvb, offset)*1.25);
+ proto_item_append_text(item, " (%g msec)", tvb_get_letohs(tvb, offset) * 1.25);
offset += 2;
item = proto_tree_add_item(tree, hf_btl2cap_max_interval, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- proto_item_append_text(item, " (%g msec)", tvb_get_letohs(tvb, offset)*1.25);
+ proto_item_append_text(item, " (%g msec)", tvb_get_letohs(tvb, offset) * 1.25);
max_interval = tvb_get_letohs(tvb, offset);
offset += 2;
item = proto_tree_add_item(tree, hf_btl2cap_slave_latency, tvb, offset, 2, ENC_LITTLE_ENDIAN);
proto_item_append_text(item, " LL Connection Events");
slave_latency = tvb_get_letohs(tvb, offset);
- if(slave_latency >= 500 || slave_latency > 10.0*tvb_get_letohs(tvb, offset+2)/(max_interval *1.25))
+ if(slave_latency >= 500 || slave_latency > 10.0 * tvb_get_letohs(tvb, offset + 2) / (max_interval *1.25))
expert_add_info_format(pinfo, item, PI_PROTOCOL, PI_WARN, "Parameter mismatch");
offset += 2;
item = proto_tree_add_item(tree, hf_btl2cap_timeout_multiplier, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- proto_item_append_text(item, " (%g sec)", tvb_get_letohs(tvb, offset)*0.01);
+ proto_item_append_text(item, " (%g sec)", tvb_get_letohs(tvb, offset) * 0.01);
offset += 2;
return offset;
@@ -1003,8 +1172,54 @@ dissect_b_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_tree
col_append_str(pinfo->cinfo, COL_INFO, "Connection oriented channel");
if (psm) {
- proto_item *psm_item;
- guint32 *service = se_tree_lookup32(psm_to_service_table, (local_service<<31) | psm);
+ proto_item *psm_item;
+ psm_service_t *psm_service;
+ emem_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 key_psm;
+ guint32 service = 0;
+ btl2cap_data_t *l2cap_data;
+
+ l2cap_data = (btl2cap_data_t *) pinfo->private_data;
+
+ interface_id = l2cap_data->interface_id;
+ adapter_id = l2cap_data->adapter_id;
+ chandle = l2cap_data->chandle;
+ key_psm = (local_service << 31) | psm;
+
+ k_interface_id = interface_id;
+ k_adapter_id = adapter_id;
+ k_chandle = chandle;
+ k_psm = key_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_chandle;
+ key[3].length = 1;
+ key[3].key = &k_psm;
+ key[4].length = 1;
+ key[4].key = &k_frame_number;
+ key[5].length = 0;
+ key[5].key = NULL;
+
+ psm_service = se_tree_lookup32_array_le(psm_to_service_table, key);
+ if (psm_service && psm_service->interface_id == interface_id &&
+ psm_service->adapter_id == adapter_id &&
+ psm_service->chandle == chandle &&
+ psm_service->psm == key_psm) {
+ service = psm_service->service;
+ }
if (psm < BTL2CAP_DYNAMIC_PSM_START) {
psm_item = proto_tree_add_uint(btl2cap_tree, hf_btl2cap_psm, tvb, offset, 0, psm);
@@ -1012,8 +1227,8 @@ dissect_b_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_tree
else {
psm_item = proto_tree_add_uint(btl2cap_tree, hf_btl2cap_psm_dynamic, tvb, offset, 0, psm);
if (service)
- proto_item_append_text(psm_item,": %s",
- val_to_str_ext_const(*service, &vs_service_classes_ext, "Unknown service"));
+ proto_item_append_text(psm_item, ": %s",
+ val_to_str_ext_const(service, &vs_service_classes_ext, "Unknown service"));
}
PROTO_ITEM_SET_GENERATED(psm_item);
@@ -1021,7 +1236,7 @@ dissect_b_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_tree
if (!dissector_try_uint(l2cap_cid_dissector_table, (guint32) cid, next_tvb, pinfo, tree)) {
if (!dissector_try_uint(l2cap_psm_dissector_table, (guint32) psm, next_tvb, pinfo, tree)) {
/* not a known fixed PSM, try to find a registered service to a dynamic PSM */
- if ((service == NULL) || !dissector_try_uint(l2cap_service_dissector_table, *service, next_tvb, pinfo, tree)) {
+ if (!dissector_try_uint(l2cap_service_dissector_table, service, next_tvb, pinfo, tree)) {
/* unknown protocol. declare as data */
proto_tree_add_item(btl2cap_tree, hf_btl2cap_payload, tvb, offset, length, ENC_NA);
}
@@ -1037,16 +1252,6 @@ dissect_b_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_tree
return offset;
}
-typedef struct _sdu_reassembly_t
-{
- guint8 *reassembled;
- guint8 seq;
- guint32 first_frame;
- guint32 last_frame;
- guint16 tot_len;
- int cur_off; /* counter used by reassembly */
-} sdu_reassembly_t;
-
static int
dissect_i_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_tree *btl2cap_tree,
psm_data_t *psm_data, guint16 length, int offset, config_data_t *config_data)
@@ -1057,7 +1262,7 @@ dissect_i_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_tree
proto_item* ti_control;
proto_tree* ti_control_subtree;
sdu_reassembly_t *mfp = NULL;
- guint16 psm = (psm_data?psm_data->psm:0);
+ guint16 psm = (psm_data ? psm_data->psm : 0);
control = tvb_get_letohs(tvb, offset);
segment = (control & 0xC000) >> 14;
@@ -1092,6 +1297,7 @@ dissect_i_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_tree
/*Segmented frames with SAR = start have an extra SDU length header field*/
if (segment == 0x01) {
proto_item *pi;
+
sdulen = tvb_get_letohs(tvb, offset);
pi = proto_tree_add_item(btl2cap_tree, hf_btl2cap_sdulength, tvb, offset, 2, ENC_LITTLE_ENDIAN);
offset += 2;
@@ -1142,8 +1348,8 @@ dissect_i_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_tree
if (segment == 0x02 || segment == 0x03) {
mfp = se_tree_lookup32_le(config_data->start_fragments, pinfo->fd->num);
if (!pinfo->fd->flags.visited) {
- if (mfp != NULL && !mfp->last_frame && (mfp->tot_len>=mfp->cur_off+length)) {
- tvb_memcpy(tvb, mfp->reassembled+mfp->cur_off, offset, length);
+ if (mfp != NULL && !mfp->last_frame && (mfp->tot_len>=mfp->cur_off + length)) {
+ tvb_memcpy(tvb, mfp->reassembled + mfp->cur_off, offset, length);
mfp->cur_off += length;
if (segment == 0x02) {
mfp->last_frame = pinfo->fd->num;
@@ -1167,8 +1373,54 @@ dissect_i_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_tree
}
if (next_tvb) {
if (psm) {
- guint32 *service = se_tree_lookup32(psm_to_service_table, ((psm_data?psm_data->local_service:0)<<31) | psm);
- proto_item *psm_item;
+ proto_item *psm_item;
+ psm_service_t *psm_service;
+ emem_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 key_psm;
+ guint32 service = 0;
+ btl2cap_data_t *l2cap_data;
+
+ l2cap_data = (btl2cap_data_t *) pinfo->private_data;
+
+ interface_id = l2cap_data->interface_id;
+ adapter_id = l2cap_data->adapter_id;
+ chandle = l2cap_data->chandle;
+ key_psm = ((psm_data ? psm_data->local_service : 0) << 31) | psm;
+
+ k_interface_id = interface_id;
+ k_adapter_id = adapter_id;
+ k_chandle = chandle;
+ k_psm = key_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_chandle;
+ key[3].length = 1;
+ key[3].key = &k_psm;
+ key[4].length = 1;
+ key[4].key = &k_frame_number;
+ key[5].length = 0;
+ key[5].key = NULL;
+
+ psm_service = se_tree_lookup32_array_le(psm_to_service_table, key);
+ if (psm_service && psm_service->interface_id == interface_id &&
+ psm_service->adapter_id == adapter_id &&
+ psm_service->chandle == chandle &&
+ psm_service->psm == key_psm) {
+ service = psm_service->service;
+ }
if (psm < BTL2CAP_DYNAMIC_PSM_START) {
psm_item = proto_tree_add_uint(btl2cap_tree, hf_btl2cap_psm, tvb, offset, 0, psm);
@@ -1176,15 +1428,15 @@ dissect_i_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_tree
else {
psm_item = proto_tree_add_uint(btl2cap_tree, hf_btl2cap_psm_dynamic, tvb, offset, 0, psm);
if (service)
- proto_item_append_text(psm_item," (%s)",
- val_to_str_ext_const(*service, &vs_service_classes_ext, "Unknown service"));
+ proto_item_append_text(psm_item, " (%s)",
+ val_to_str_ext_const(service, &vs_service_classes_ext, "Unknown service"));
}
PROTO_ITEM_SET_GENERATED(psm_item);
/* call next dissector */
if (!dissector_try_uint(l2cap_psm_dissector_table, (guint32) psm, next_tvb, pinfo, tree)) {
/* not a known fixed PSM, try to find a registered service to a dynamic PSM */
- if ((service == NULL) || !dissector_try_uint(l2cap_service_dissector_table, *service, next_tvb, pinfo, tree)) {
+ if (!dissector_try_uint(l2cap_service_dissector_table, service, next_tvb, pinfo, tree)) {
/* unknown protocol. declare as data */
proto_tree_add_item(btl2cap_tree, hf_btl2cap_payload, next_tvb, 0, tvb_length(next_tvb), ENC_NA);
}
@@ -1209,6 +1461,7 @@ dissect_s_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree _U_, proto_t
guint16 control;
control = tvb_get_letohs(tvb, offset);
+
switch ((control & 0x000C) >> 2) {
case 0:
col_append_str(pinfo->cinfo, COL_INFO, "[S] Receiver Ready");
@@ -1220,19 +1473,23 @@ dissect_s_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree _U_, proto_t
col_append_str(pinfo->cinfo, COL_INFO, "[S] Unknown supervisory frame");
break;
}
+
ti_control = proto_tree_add_none_format(btl2cap_tree, hf_btl2cap_control, tvb,
offset, 2, "Control: %s reqseq:%d r:%d",
val_to_str_const((control & 0x000C) >> 2, control_supervisory_vals, "unknown"),
(control & 0x3F00) >> 8,
(control & 0x0080) >> 7);
ti_control_subtree = proto_item_add_subtree(ti_control, ett_btl2cap_control);
+
proto_tree_add_item(ti_control_subtree, hf_btl2cap_control_reqseq, tvb, offset, 2, ENC_LITTLE_ENDIAN);
proto_tree_add_item(ti_control_subtree, hf_btl2cap_control_retransmissiondisable, tvb, offset, 2, ENC_LITTLE_ENDIAN);
proto_tree_add_item(ti_control_subtree, hf_btl2cap_control_supervisory, tvb, offset, 2, ENC_LITTLE_ENDIAN);
proto_tree_add_item(ti_control_subtree, hf_btl2cap_control_type, tvb, offset, 2, ENC_LITTLE_ENDIAN);
offset += 2;
+
proto_tree_add_item(btl2cap_tree, hf_btl2cap_fcs, tvb, offset, 2, ENC_LITTLE_ENDIAN);
offset += 2;
+
return offset;
}
@@ -1246,7 +1503,8 @@ dissect_btl2cap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
int offset = 0;
proto_tree *btl2cap_tree = NULL;
- guint16 length, cid;
+ guint16 length;
+ guint16 cid;
guint16 psm;
guint16 control;
tvbuff_t *next_tvb = NULL;
@@ -1294,9 +1552,9 @@ dissect_btl2cap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
acl_data = (bthci_acl_data_t *)pinfo->private_data;
l2cap_data = ep_alloc(sizeof(btl2cap_data_t));
- l2cap_data->interface_id = (acl_data)? acl_data->interface_id : HCI_INTERFACE_AMP;
- l2cap_data->adapter_id = (acl_data)? acl_data->adapter_id : HCI_ADAPTER_DEFAULT;
- l2cap_data->chandle = (acl_data)? acl_data->chandle : 0;
+ l2cap_data->interface_id = (acl_data) ? acl_data->interface_id : HCI_INTERFACE_AMP;
+ l2cap_data->adapter_id = (acl_data) ? acl_data->adapter_id : HCI_ADAPTER_DEFAULT;
+ l2cap_data->chandle = (acl_data) ? acl_data->chandle : 0;
l2cap_data->cid = cid;
l2cap_data->psm = 0;
l2cap_data->first_scid_frame = 0;
@@ -1306,7 +1564,7 @@ dissect_btl2cap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
if (cid == BTL2CAP_FIXED_CID_SIGNAL || cid == BTL2CAP_FIXED_CID_LE_SIGNAL) {
/* This is a command packet*/
- while (offset < (length+4)) {
+ while (offset < (length + 4)) {
proto_item *ti_command;
proto_tree *btl2cap_cmd_tree;
guint8 cmd_code;
@@ -1328,11 +1586,11 @@ dissect_btl2cap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
cmd_length = tvb_get_letohs(tvb, offset);
proto_tree_add_item(btl2cap_cmd_tree, hf_btl2cap_cmd_length, tvb, offset, 2, ENC_LITTLE_ENDIAN);
- proto_item_set_len(ti_command, cmd_length+4);
+ proto_item_set_len(ti_command, cmd_length + 4);
offset += 2;
cmd_str = val_to_str_const(cmd_code, command_code_vals, "Unknown cmd");
- proto_item_append_text(ti_command,"%s", cmd_str);
+ proto_item_append_text(ti_command, "%s", cmd_str);
col_append_fstr(pinfo->cinfo, COL_INFO, "%s", cmd_str);
switch (cmd_code) {
@@ -1432,10 +1690,48 @@ dissect_btl2cap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
/* call next dissector */
if (!dissector_try_uint(l2cap_psm_dissector_table, (guint32) psm, next_tvb, pinfo, tree)) {
/* not a known fixed PSM, try to find a registered service to a dynamic PSM */
- guint32 *service;
- service = se_tree_lookup32(psm_to_service_table, ((pinfo->p2p_dir == P2P_DIR_RECV)?0x80000000:0) | psm);
-
- if ((service == NULL) || !dissector_try_uint(l2cap_service_dissector_table, *service, next_tvb, pinfo, tree)) {
+ psm_service_t *psm_service;
+ emem_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 key_psm;
+
+ interface_id = l2cap_data->interface_id;
+ adapter_id = l2cap_data->adapter_id;
+ chandle = l2cap_data->chandle;
+ key_psm = ((pinfo->p2p_dir == P2P_DIR_RECV) ? 0x80000000 : 0x00000000) | psm;
+
+ k_interface_id = interface_id;
+ k_adapter_id = adapter_id;
+ k_chandle = chandle;
+ k_psm = key_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_chandle;
+ key[3].length = 1;
+ key[3].key = &k_psm;
+ key[4].length = 1;
+ key[4].key = &k_frame_number;
+ key[5].length = 0;
+ key[5].key = NULL;
+
+ psm_service = se_tree_lookup32_array_le(psm_to_service_table, key);
+ if (!(psm_service && psm_service->interface_id == interface_id &&
+ psm_service->adapter_id == adapter_id &&
+ psm_service->chandle == chandle &&
+ psm_service->psm == key_psm &&
+ dissector_try_uint(l2cap_service_dissector_table, psm_service->service, next_tvb, pinfo, tree))) {
/* unknown protocol. declare as data */
proto_tree_add_item(btl2cap_tree, hf_btl2cap_payload, tvb, offset, length, ENC_NA);
}
@@ -1479,40 +1775,62 @@ dissect_btl2cap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
}
}
else /* if (cid >= BTL2CAP_FIXED_CID_MAX) */ { /* Connection oriented channel */
- emem_tree_key_t key[3];
- guint32 kcid;
- guint32 frame_number;
-
- frame_number = pinfo->fd->num;
- kcid = cid | ((pinfo->p2p_dir == P2P_DIR_RECV) ? 0x0000 : 0x8000);
+ emem_tree_key_t key[6];
+ guint32 k_interface_id;
+ guint32 k_adapter_id;
+ guint32 k_chandle;
+ guint32 k_cid;
+ guint32 k_frame_number;
+ guint32 interface_id;
+ guint32 adapter_id;
+ guint32 chandle;
+ guint32 key_cid;
+
+ interface_id = (acl_data) ? acl_data->interface_id : HCI_INTERFACE_AMP;
+ adapter_id = (acl_data) ? acl_data->adapter_id : HCI_ADAPTER_DEFAULT;
+ chandle = (acl_data) ? acl_data->chandle : 0;
+ key_cid = cid | ((pinfo->p2p_dir == P2P_DIR_RECV) ? 0x00000000 : 0x80000000);
+
+ k_interface_id = interface_id;
+ k_adapter_id = adapter_id;
+ k_chandle = chandle;
+ k_cid = key_cid;
+ k_frame_number = pinfo->fd->num;
key[0].length = 1;
- key[0].key = &kcid;
+ key[0].key = &k_interface_id;
key[1].length = 1;
- key[1].key = &frame_number;
- key[2].length = 0;
- key[2].key = NULL;
+ key[1].key = &k_adapter_id;
+ key[2].length = 1;
+ key[2].key = &k_chandle;
+ key[3].length = 1;
+ key[3].key = &k_cid;
+ key[4].length = 1;
+ key[4].key = &k_frame_number;
+ key[5].length = 0;
+ key[5].key = NULL;
psm_data = se_tree_lookup32_array_le(cid_to_psm_table, key);
+ if (psm_data && psm_data->interface_id == interface_id &&
+ psm_data->adapter_id == adapter_id &&
+ psm_data->chandle == chandle &&
+ (psm_data->scid == key_cid ||
+ psm_data->dcid == key_cid)) {
- if (psm_data &&
- ((psm_data->scid == (cid | ((pinfo->p2p_dir == P2P_DIR_RECV) ? 0x0000 : 0x8000))) ||
- (psm_data->dcid == (cid | ((pinfo->p2p_dir == P2P_DIR_RECV) ? 0x0000 : 0x8000))))) {
-
- if ((psm_data->scid == (cid | ((pinfo->p2p_dir == P2P_DIR_RECV) ? 0x0000 : 0x8000))) &&
+ if ((psm_data->scid == key_cid) &&
psm_data->first_scid_frame == 0) {
psm_data->first_scid_frame = pinfo->fd->num;
}
- if ((psm_data->dcid == (cid | ((pinfo->p2p_dir == P2P_DIR_RECV) ? 0x0000 : 0x8000))) &&
+ if ((psm_data->dcid == key_cid) &&
psm_data->first_dcid_frame == 0) {
psm_data->first_dcid_frame = pinfo->fd->num;
}
psm = psm_data->psm;
l2cap_data->psm = psm;
- l2cap_data->first_scid_frame = psm_data->first_scid_frame;
- l2cap_data->first_dcid_frame = psm_data->first_dcid_frame;
+ l2cap_data->first_scid_frame = psm_data->first_scid_frame;
+ l2cap_data->first_dcid_frame = psm_data->first_dcid_frame;
if (pinfo->p2p_dir == P2P_DIR_RECV)
config_data = &(psm_data->in);
@@ -1543,16 +1861,80 @@ btl2cap_sdp_tap_packet(void *arg _U_, packet_info *pinfo _U_, epan_dissect_t *ed
btsdp_data_t *sdp_data = (btsdp_data_t *) arg2;
if (sdp_data->protocol == BTSDP_L2CAP_PROTOCOL_UUID) {
- guint32 token, *psm_service;
+ psm_service_t *psm_service;
+ emem_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;
+ btl2cap_data_t *l2cap_data;
+
+ l2cap_data = (btl2cap_data_t *) pinfo->private_data;
+
+ interface_id = l2cap_data->interface_id;
+ adapter_id = l2cap_data->adapter_id;
+ chandle = l2cap_data->chandle;
+ psm = sdp_data->channel | ((sdp_data->flags & BTSDP_LOCAL_SERVICE_FLAG_MASK) << 31);
+
+ k_interface_id = interface_id;
+ k_adapter_id = adapter_id;
+ k_chandle = chandle;
+ k_psm = psm;
+ k_frame_number = pinfo->fd->num;
- token = sdp_data->channel | ((sdp_data->flags & BTSDP_LOCAL_SERVICE_FLAG_MASK)<<31);
-
- psm_service = se_tree_lookup32(psm_to_service_table, token);
- if (!psm_service) {
- psm_service = se_alloc0(sizeof(guint32));
- se_tree_insert32(psm_to_service_table, token, psm_service);
+ 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_chandle;
+ key[3].length = 1;
+ key[3].key = &k_psm;
+ key[4].length = 1;
+ key[4].key = &k_frame_number;
+ key[5].length = 0;
+ key[5].key = NULL;
+
+
+ psm_service = se_tree_lookup32_array_le(psm_to_service_table, key);
+ if (!(psm_service && psm_service->interface_id == interface_id &&
+ psm_service->adapter_id == adapter_id &&
+ psm_service->chandle == chandle &&
+ psm_service->psm == psm)) {
+ psm_service = se_alloc0(sizeof(psm_service_t));
+ psm_service->interface_id = interface_id;
+ psm_service->adapter_id = adapter_id;
+ psm_service->chandle = chandle;
+ psm_service->psm = psm;
+ psm_service->service = 0;
+
+ k_interface_id = interface_id;
+ k_adapter_id = adapter_id;
+ k_chandle = chandle;
+ k_psm = 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_chandle;
+ key[3].length = 1;
+ key[3].key = &k_psm;
+ key[4].length = 1;
+ key[4].key = &k_frame_number;
+ key[5].length = 0;
+ key[5].key = NULL;
+
+ se_tree_insert32_array(psm_to_service_table, key, psm_service);
}
- *psm_service = sdp_data->service;
+ psm_service->service = sdp_data->service;
}
return 0;
}
@@ -1572,7 +1954,7 @@ proto_register_btl2cap(void)
},
{ &hf_btl2cap_cid,
{ "CID", "btl2cap.cid",
- FT_UINT16, BASE_HEX, NULL, 0x0,
+ FT_UINT16, BASE_HEX | BASE_RANGE_STRING, RVALS(cid_rvals), 0x0,
"L2CAP Channel Identifier", HFILL }
},
{ &hf_btl2cap_payload,
@@ -1617,17 +1999,17 @@ proto_register_btl2cap(void)
},
{ &hf_btl2cap_scid,
{ "Source CID", "btl2cap.scid",
- FT_UINT16, BASE_HEX, NULL, 0x0,
+ FT_UINT16, BASE_HEX | BASE_RANGE_STRING, RVALS(cid_rvals), 0x0,
"Source Channel Identifier", HFILL }
},
{ &hf_btl2cap_dcid,
{ "Destination CID", "btl2cap.dcid",
- FT_UINT16, BASE_HEX, NULL, 0x0,
+ FT_UINT16, BASE_HEX | BASE_RANGE_STRING, RVALS(cid_rvals), 0x0,
"Destination Channel Identifier", HFILL }
},
{ &hf_btl2cap_icid,
{ "Initiator CID", "btl2cap.icid",
- FT_UINT16, BASE_HEX, NULL, 0x0,
+ FT_UINT16, BASE_HEX | BASE_RANGE_STRING, RVALS(cid_rvals), 0x0,
"Initiator Channel Identifier", HFILL }
},
{ &hf_btl2cap_controller,