diff options
author | Michael Mann <mmann78@netscape.net> | 2013-02-21 22:00:32 +0000 |
---|---|---|
committer | Michael Mann <mmann78@netscape.net> | 2013-02-21 22:00:32 +0000 |
commit | e094c213016f483a3d02deccd49cebc5f0e9797d (patch) | |
tree | 98f63fb2617ceba41113c92b693089e71cd9809c /epan/dissectors | |
parent | bfeeba6f5e9ae0994842992c04670247c71bd879 (diff) |
Minor Bluetooth fixes
1. Allow to DecodeBy payload over AVCTP
2. Fix L2CAP CID payload recognize after disc
3. Removed unneeded _U_
4. Fall back to control channel in AVRCP
5. Fix time-tracking for passthrough and capability AVRCP commands
From Michal Labedzki, bug 8367 (https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=8367)
svn path=/trunk/; revision=47810
Diffstat (limited to 'epan/dissectors')
-rw-r--r-- | epan/dissectors/packet-btavctp.c | 16 | ||||
-rw-r--r-- | epan/dissectors/packet-btavrcp.c | 70 | ||||
-rw-r--r-- | epan/dissectors/packet-bthci_cmd.c | 10 | ||||
-rw-r--r-- | epan/dissectors/packet-bthci_evt.c | 44 | ||||
-rw-r--r-- | epan/dissectors/packet-btl2cap.c | 114 |
5 files changed, 184 insertions, 70 deletions
diff --git a/epan/dissectors/packet-btavctp.c b/epan/dissectors/packet-btavctp.c index d31bbf4fad..750d2e95b2 100644 --- a/epan/dissectors/packet-btavctp.c +++ b/epan/dissectors/packet-btavctp.c @@ -51,7 +51,8 @@ static int hf_btavctp_number_of_packets = -1; static gint ett_btavctp = -1; -static dissector_handle_t btavrcp_handle = NULL; +static dissector_table_t avctp_service_dissector_table; + static dissector_handle_t data_handle = NULL; typedef struct _fragment_t { @@ -187,10 +188,10 @@ dissect_btavctp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) /* reassembling */ next_tvb = tvb_new_subset(tvb, offset, length, length); if (packet_type == PACKET_TYPE_SINGLE) { - if (pid == BTSDP_AVRCP_SERVICE_UUID && btavrcp_handle != NULL) - call_dissector(btavrcp_handle, next_tvb, pinfo, tree); - else + if (!dissector_try_uint(avctp_service_dissector_table, pid, next_tvb, pinfo, tree)) { call_dissector(data_handle, next_tvb, pinfo, tree); + } + } else { emem_tree_key_t key[6]; guint32 k_interface_id; @@ -377,9 +378,7 @@ dissect_btavctp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) next_tvb = tvb_new_child_real_data(tvb, reassembled, length, length); add_new_data_source(pinfo, next_tvb, "Reassembled AVCTP"); - if (fragments->pid == BTSDP_AVRCP_SERVICE_UUID && btavrcp_handle != NULL) { - call_dissector(btavrcp_handle, next_tvb, pinfo, tree); - } else { + if (!dissector_try_uint(avctp_service_dissector_table, fragments->pid, next_tvb, pinfo, tree)) { call_dissector(data_handle, next_tvb, pinfo, tree); } } @@ -442,6 +441,8 @@ proto_register_btavctp(void) reassembling = se_tree_create(EMEM_TREE_TYPE_RED_BLACK, "btavctp reassembling"); + avctp_service_dissector_table = register_dissector_table("btavctp.service", "AVCTP Service", FT_UINT16, BASE_HEX); + proto_btavctp = proto_register_protocol("Bluetooth AVCTP Protocol", "AVCTP", "btavctp"); register_dissector("btavctp", dissect_btavctp, proto_btavctp); @@ -461,7 +462,6 @@ proto_reg_handoff_btavctp(void) dissector_handle_t btavctp_handle; btavctp_handle = find_dissector("btavctp"); - btavrcp_handle = find_dissector("btavrcp"); data_handle = find_dissector("data"); dissector_add_uint("btl2cap.service", BTSDP_AVCTP_PROTOCOL_UUID, btavctp_handle); diff --git a/epan/dissectors/packet-btavrcp.c b/epan/dissectors/packet-btavrcp.c index f5d1a3c883..1f9813aa41 100644 --- a/epan/dissectors/packet-btavrcp.c +++ b/epan/dissectors/packet-btavrcp.c @@ -290,6 +290,7 @@ typedef struct _timing_info { guint32 psm; guint32 opcode; guint32 op; + guint32 op_arg; } timing_info_t; static const value_string packet_type_vals[] = { @@ -916,13 +917,14 @@ dissect_item_folder(tvbuff_t *tvb, proto_tree *tree, gint offset) static gint dissect_passthrough(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, - gint offset, gboolean is_command) + gint offset, gboolean is_command, guint32 *op) { guint operation; guint state; proto_tree_add_item(tree, hf_btavrcp_passthrough_state, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(tree, hf_btavrcp_passthrough_operation, tvb, offset, 1, ENC_BIG_ENDIAN); + *op = tvb_get_guint8(tvb, offset); operation = tvb_get_guint8(tvb, offset) & 0x7F; state = (tvb_get_guint8(tvb, offset) & 0x80) >> 7; offset += 1; @@ -989,7 +991,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, + gint offset, guint ctype, guint32 *op, guint32 *op_arg, gboolean is_command) { guint pdu_id; @@ -1013,6 +1015,8 @@ dissect_vendor_dependant(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, avctp_data = (btavctp_data_t *) pinfo->private_data; + *op_arg = 0; + interface_id = avctp_data->interface_id; adapter_id = avctp_data->adapter_id; chandle = avctp_data->chandle; @@ -1256,7 +1260,7 @@ dissect_vendor_dependant(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_tree_add_item(tree, hf_btavrcp_capability, tvb, offset, 1, ENC_BIG_ENDIAN); capability = tvb_get_guint8(tvb, offset); - *op |= capability << 8; + *op_arg = capability; col_append_fstr(pinfo->cinfo, COL_INFO, "(%s)", val_to_str_const(capability, capability_vals, "unknown")); offset += 1; @@ -1267,7 +1271,7 @@ dissect_vendor_dependant(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_tree_add_item(tree, hf_btavrcp_capability, tvb, offset, 1, ENC_BIG_ENDIAN); capability = tvb_get_guint8(tvb, offset); - *op |= capability << 8; + *op_arg = capability; offset += 1; proto_tree_add_item(tree, hf_btavrcp_capability_count, tvb, offset, 1, ENC_BIG_ENDIAN); capability_count = tvb_get_guint8(tvb, offset); @@ -1528,7 +1532,7 @@ dissect_vendor_dependant(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, break; case PDU_REGISTER_NOTIFICATION: event_id = tvb_get_guint8(tvb, offset); - *op |= event_id << 8; + *op_arg = event_id; col_append_fstr(pinfo->cinfo, COL_INFO, " - %s", val_to_str_const(event_id, notification_vals, "Unknown Event ID")); @@ -2098,18 +2102,20 @@ dissect_btavrcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) gint offset = 0; guint32 opcode; guint32 op = 0; + guint32 op_arg = 0; guint ctype; guint response_time; guint max_response_time; guint is_command; timing_info_t *timing_info; - emem_tree_key_t key[8]; + emem_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; @@ -2152,7 +2158,10 @@ dissect_btavrcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) chandle = avctp_data->chandle; psm = avctp_data->psm; - if (avctp_data->psm == BTL2CAP_PSM_AVCTP_CTRL) { + if (avctp_data->psm == BTL2CAP_PSM_AVCTP_BRWS) { + col_append_str(pinfo->cinfo, COL_INFO, "Browsing"); + offset = dissect_browsing(tvb, pinfo, btavrcp_tree, offset, is_command); + } else { 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); ctype = tvb_get_guint8(tvb, offset) & 0x0F; @@ -2170,7 +2179,8 @@ dissect_btavrcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) switch(opcode) { case OPCODE_PASSTHROUGH: - offset = dissect_passthrough(tvb, pinfo, btavrcp_tree, offset, is_command); + offset = dissect_passthrough(tvb, pinfo, btavrcp_tree, offset, + is_command, &op); break; case OPCODE_UNIT: offset = dissect_unit(tvb, btavrcp_tree, offset, is_command); @@ -2179,7 +2189,8 @@ dissect_btavrcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) offset = dissect_subunit(tvb, btavrcp_tree, offset, is_command); break; case OPCODE_VENDOR_DEPENDANT: - offset = dissect_vendor_dependant(tvb, pinfo, btavrcp_tree, offset, ctype, &op, is_command); + offset = dissect_vendor_dependant(tvb, pinfo, btavrcp_tree, + offset, ctype, &op, &op_arg, is_command); break; }; @@ -2189,6 +2200,7 @@ dissect_btavrcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) k_psm = psm; k_opcode = opcode; k_op = op; + k_op_arg = (ctype == 0x0a) ? G_MAXUINT32 : op_arg; k_frame_number = pinfo->fd->num; key[0].length = 1; @@ -2204,9 +2216,11 @@ dissect_btavrcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) 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; + key[6].key = &k_op_arg; + key[7].length = 1; + key[7].key = &k_frame_number; + key[8].length = 0; + key[8].key = NULL; if (pinfo->fd->flags.visited == 0) { if (is_command) { @@ -2233,6 +2247,7 @@ dissect_btavrcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) timing_info->psm = psm; timing_info->opcode = opcode; timing_info->op = op; + timing_info->op_arg = op_arg; timing_info->used = 0; se_tree_insert32_array(timing, key, timing_info); @@ -2244,6 +2259,7 @@ dissect_btavrcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) timing_info->psm == psm && timing_info->opcode == opcode && timing_info->op == op && + ((ctype == 0x0a) ? 1 : (timing_info->op_arg == op_arg)) && timing_info->used == 0) { timing_info->response_frame_number = pinfo->fd->num; timing_info->response_timestamp = pinfo->fd->abs_ts; @@ -2257,6 +2273,7 @@ dissect_btavrcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) k_psm = psm; k_opcode = opcode; k_op = op; + k_op_arg = (ctype == 0x0a) ? G_MAXUINT32 : op_arg; k_frame_number = pinfo->fd->num; key[0].length = 1; @@ -2272,9 +2289,12 @@ dissect_btavrcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) 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; + key[6].key = &k_op_arg; + key[7].length = 1; + key[7].key = &k_frame_number; + key[8].length = 0; + key[8].key = NULL; + } timing_info = se_tree_lookup32_array_le(timing, key); @@ -2283,7 +2303,8 @@ dissect_btavrcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) timing_info->chandle == chandle && timing_info->psm == psm && timing_info->opcode == opcode && - timing_info->op == op) { + timing_info->op == op && + ((ctype == 0x0a) ? 1 : (timing_info->op_arg == op_arg))) { if (timing_info->command_timestamp.nsecs > timing_info->response_timestamp.nsecs) { response_time = timing_info->response_timestamp.nsecs + (1000000000 - timing_info->command_timestamp.nsecs); @@ -2318,9 +2339,6 @@ dissect_btavrcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) } - } else { - col_append_str(pinfo->cinfo, COL_INFO, "Browsing"); - offset = dissect_browsing(tvb, pinfo, btavrcp_tree, offset, is_command); } if (tvb_reported_length_remaining(tvb, offset) > 0) { @@ -2369,7 +2387,7 @@ proto_register_btavrcp(void) NULL, HFILL } }, { &hf_btavrcp_passthrough_state, - { "RFA", "btavrcp.passthrough.state", + { "State", "btavrcp.passthrough.state", FT_UINT8, BASE_HEX, VALS(passthrough_state_vals), 0x80, NULL, HFILL } }, @@ -3120,6 +3138,18 @@ proto_register_btavrcp(void) "Version of profile supported by this dissector."); } +void +proto_reg_handoff_btavrcp(void) +{ + dissector_handle_t btavrcp_handle; + + btavrcp_handle = find_dissector("btavrcp"); + + dissector_add_uint("btavctp.service", BTSDP_AVRCP_TG_SERVICE_UUID, btavrcp_handle); + dissector_add_uint("btavctp.service", BTSDP_AVRCP_CT_SERVICE_UUID, btavrcp_handle); + dissector_add_uint("btavctp.service", BTSDP_AVRCP_SERVICE_UUID, btavrcp_handle); +} + /* * Editor modelines - http://www.wireshark.org/tools/modelines.html diff --git a/epan/dissectors/packet-bthci_cmd.c b/epan/dissectors/packet-bthci_cmd.c index c51d4e2a5d..9770d80f55 100644 --- a/epan/dissectors/packet-bthci_cmd.c +++ b/epan/dissectors/packet-bthci_cmd.c @@ -1174,7 +1174,7 @@ dissect_bthci_cmd_cod(int type, tvbuff_t *tvb, int offset, packet_info *pinfo _U } static int -dissect_bthci_eir_ad_data(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, guint8 size) +dissect_bthci_eir_ad_data(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, guint8 size) { guint8 length, type, data_size = size; guint16 i, j; @@ -1335,7 +1335,7 @@ dissect_bthci_cmd_flow_spec(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, p } static int -dissect_link_control_cmd(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, guint16 cmd_ocf) +dissect_link_control_cmd(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, guint16 cmd_ocf) { proto_item *item; guint32 clock_value; @@ -1673,7 +1673,7 @@ dissect_link_control_cmd(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, prot } static int -dissect_link_policy_cmd(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, guint16 cmd_ocf) +dissect_link_policy_cmd(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, guint16 cmd_ocf) { proto_item *item; guint16 timeout; @@ -1816,7 +1816,7 @@ return offset; } static int -dissect_host_controller_baseband_cmd(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, +dissect_host_controller_baseband_cmd(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, guint16 cmd_ocf) { proto_item *item; @@ -2431,7 +2431,7 @@ return offset; } static void -dissect_le_cmd(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, guint16 cmd_ocf) +dissect_le_cmd(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, guint16 cmd_ocf) { proto_item *item; diff --git a/epan/dissectors/packet-bthci_evt.c b/epan/dissectors/packet-bthci_evt.c index e72e5173ad..2ab049fa73 100644 --- a/epan/dissectors/packet-bthci_evt.c +++ b/epan/dissectors/packet-bthci_evt.c @@ -987,7 +987,7 @@ dissect_bthci_evt_conn_complete(tvbuff_t *tvb, int offset, packet_info *pinfo, p } static int -dissect_bthci_evt_conn_request(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree) +dissect_bthci_evt_conn_request(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) { offset = dissect_bthci_evt_bd_addr(tvb, offset, pinfo, tree, NULL); @@ -1112,7 +1112,7 @@ dissect_bthci_evt_lmp_features(tvbuff_t *tvb, int offset, packet_info *pinfo _U_ } static int -dissect_bthci_evt_pin_code_request(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree) +dissect_bthci_evt_pin_code_request(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) { offset = dissect_bthci_evt_bd_addr(tvb, offset, pinfo, tree, NULL); @@ -1120,7 +1120,7 @@ dissect_bthci_evt_pin_code_request(tvbuff_t *tvb, int offset, packet_info *pinfo } static int -dissect_bthci_evt_link_key_request(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree) +dissect_bthci_evt_link_key_request(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) { offset = dissect_bthci_evt_bd_addr(tvb, offset, pinfo, tree, NULL); @@ -1128,7 +1128,7 @@ dissect_bthci_evt_link_key_request(tvbuff_t *tvb, int offset, packet_info *pinfo } static int -dissect_bthci_evt_link_key_notification(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree) +dissect_bthci_evt_link_key_notification(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) { offset = dissect_bthci_evt_bd_addr(tvb, offset, pinfo, tree, NULL); @@ -1142,7 +1142,7 @@ dissect_bthci_evt_link_key_notification(tvbuff_t *tvb, int offset, packet_info * } static int -dissect_bthci_evt_return_link_keys(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree) +dissect_bthci_evt_return_link_keys(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) { guint8 evt_num_keys; @@ -1298,7 +1298,7 @@ dissect_bthci_evt_mode_change(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, } static int -dissect_bthci_evt_role_change(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree) +dissect_bthci_evt_role_change(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) { proto_tree_add_item(tree, hf_bthci_evt_status, tvb, offset, 1, ENC_LITTLE_ENDIAN); offset++; @@ -1321,7 +1321,7 @@ dissect_bthci_evt_hardware_error(tvbuff_t *tvb, int offset, packet_info *pinfo _ } static int -dissect_bthci_evt_loopback_command(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree) +dissect_bthci_evt_loopback_command(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) { tvbuff_t *next_tvb; @@ -1482,7 +1482,7 @@ dissect_bthci_evt_command_status(tvbuff_t *tvb, int offset, packet_info *pinfo, } static int -dissect_bthci_evt_page_scan_mode_change(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree) +dissect_bthci_evt_page_scan_mode_change(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) { offset = dissect_bthci_evt_bd_addr(tvb, offset, pinfo, tree, NULL); @@ -1493,7 +1493,7 @@ dissect_bthci_evt_page_scan_mode_change(tvbuff_t *tvb, int offset, packet_info * } static int -dissect_bthci_evt_page_scan_repetition_mode_change(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree) +dissect_bthci_evt_page_scan_repetition_mode_change(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) { offset = dissect_bthci_evt_bd_addr(tvb, offset, pinfo, tree, NULL); @@ -1716,7 +1716,7 @@ dissect_bthci_evt_eir_ad_data(tvbuff_t *tvb, int offset, packet_info *pinfo, } static int -dissect_bthci_evt_io_capability_request(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree) +dissect_bthci_evt_io_capability_request(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) { offset = dissect_bthci_evt_bd_addr(tvb, offset, pinfo, tree, NULL); @@ -1724,7 +1724,7 @@ dissect_bthci_evt_io_capability_request(tvbuff_t *tvb, int offset, packet_info * } static int -dissect_bthci_evt_io_capability_response(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree) +dissect_bthci_evt_io_capability_response(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) { offset = dissect_bthci_evt_bd_addr(tvb, offset, pinfo, tree, NULL); @@ -1741,7 +1741,7 @@ dissect_bthci_evt_io_capability_response(tvbuff_t *tvb, int offset, packet_info } static int -dissect_bthci_evt_user_confirmation_request(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree) +dissect_bthci_evt_user_confirmation_request(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) { offset = dissect_bthci_evt_bd_addr(tvb, offset, pinfo, tree, NULL); @@ -1752,7 +1752,7 @@ dissect_bthci_evt_user_confirmation_request(tvbuff_t *tvb, int offset, packet_in } static int -dissect_bthci_evt_user_passkey_request(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree) +dissect_bthci_evt_user_passkey_request(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) { offset = dissect_bthci_evt_bd_addr(tvb, offset, pinfo, tree, NULL); @@ -1760,7 +1760,7 @@ dissect_bthci_evt_user_passkey_request(tvbuff_t *tvb, int offset, packet_info *p } static int -dissect_bthci_evt_remote_oob_data_request(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree) +dissect_bthci_evt_remote_oob_data_request(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) { offset = dissect_bthci_evt_bd_addr(tvb, offset, pinfo, tree, NULL); @@ -1768,7 +1768,7 @@ dissect_bthci_evt_remote_oob_data_request(tvbuff_t *tvb, int offset, packet_info } static int -dissect_bthci_evt_simple_pairing_complete(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree) +dissect_bthci_evt_simple_pairing_complete(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) { proto_tree_add_item(tree, hf_bthci_evt_status, tvb, offset, 1, ENC_LITTLE_ENDIAN); offset++; @@ -1779,7 +1779,7 @@ dissect_bthci_evt_simple_pairing_complete(tvbuff_t *tvb, int offset, packet_info } static int -dissect_bthci_evt_user_passkey_notification(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree) +dissect_bthci_evt_user_passkey_notification(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) { offset = dissect_bthci_evt_bd_addr(tvb, offset, pinfo, tree, NULL); @@ -1790,7 +1790,7 @@ dissect_bthci_evt_user_passkey_notification(tvbuff_t *tvb, int offset, packet_in } static int -dissect_bthci_evt_keypress_notification(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree) +dissect_bthci_evt_keypress_notification(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) { offset = dissect_bthci_evt_bd_addr(tvb, offset, pinfo, tree, NULL); @@ -1801,7 +1801,7 @@ dissect_bthci_evt_keypress_notification(tvbuff_t *tvb, int offset, packet_info * } static int -dissect_bthci_evt_remote_host_sup_feat_notification(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree) +dissect_bthci_evt_remote_host_sup_feat_notification(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) { offset = dissect_bthci_evt_bd_addr(tvb, offset, pinfo, tree, NULL); @@ -1812,7 +1812,7 @@ dissect_bthci_evt_remote_host_sup_feat_notification(tvbuff_t *tvb, int offset, p } static int -dissect_bthci_evt_le_meta(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree) +dissect_bthci_evt_le_meta(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) { proto_item *item; guint8 subevent_code; @@ -3113,7 +3113,7 @@ dissect_bthci_evt_encryption_change(tvbuff_t *tvb, int offset, packet_info *pinf } static int -dissect_bthci_evt_read_remote_ext_features_complete(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree) +dissect_bthci_evt_read_remote_ext_features_complete(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) { guint8 page_number; @@ -3142,7 +3142,7 @@ dissect_bthci_evt_read_remote_ext_features_complete(tvbuff_t *tvb, int offset, p } static int -dissect_bthci_evt_sync_connection_complete(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree) +dissect_bthci_evt_sync_connection_complete(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) { proto_item *item; @@ -3305,7 +3305,7 @@ dissect_bthci_evt_link_supervision_timeout_changed(tvbuff_t *tvb, int offset, pa } static int -dissect_bthci_evt_inq_result(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree) +dissect_bthci_evt_inq_result(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) { guint8 num, evt_num_responses; diff --git a/epan/dissectors/packet-btl2cap.c b/epan/dissectors/packet-btl2cap.c index 1cdc361e36..d79cdb0201 100644 --- a/epan/dissectors/packet-btl2cap.c +++ b/epan/dissectors/packet-btl2cap.c @@ -172,6 +172,7 @@ typedef struct _psm_data_t { guint32 first_dcid_frame; guint16 psm; gboolean local_service; + guint32 disconnect_in_frame; config_data_t in; config_data_t out; } psm_data_t; @@ -509,6 +510,7 @@ dissect_connrequest(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *t psm_data->interface_id = k_interface_id; psm_data->adapter_id = k_adapter_id; psm_data->chandle = k_chandle; + psm_data->disconnect_in_frame = G_MAXUINT32; key[0].length = 1; key[0].key = &k_interface_id; @@ -529,7 +531,7 @@ dissect_connrequest(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *t } static int -dissect_movechanrequest(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree) +dissect_movechanrequest(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) { guint16 icid; guint8 ctrl_id; @@ -686,7 +688,7 @@ 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) +dissect_configrequest(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, guint16 length) { psm_data_t *psm_data; config_data_t *config_data; @@ -742,7 +744,8 @@ dissect_configrequest(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_t 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))) { + psm_data->dcid == cid && + psm_data->disconnect_in_frame > pinfo->fd->num) { if (pinfo->p2p_dir == P2P_DIR_RECV) config_data = &(psm_data->out); else @@ -758,7 +761,7 @@ dissect_configrequest(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_t static int -dissect_inforequest(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree) +dissect_inforequest(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) { guint16 info_type; @@ -771,7 +774,7 @@ dissect_inforequest(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tre } static int -dissect_inforesponse(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree) +dissect_inforesponse(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) { guint16 info_type, result; @@ -867,7 +870,7 @@ 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) +dissect_configresponse(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, guint16 length) { psm_data_t *psm_data; config_data_t *config_data; @@ -929,7 +932,8 @@ dissect_configresponse(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_ 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))) { + psm_data->scid == cid && + psm_data->disconnect_in_frame > pinfo->fd->num) { if (pinfo->p2p_dir == P2P_DIR_RECV) config_data = &(psm_data->out); else @@ -1050,7 +1054,7 @@ dissect_chanresponse(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree * } static int -dissect_movechanresponse(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree) +dissect_movechanresponse(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) { guint16 icid, result; @@ -1069,7 +1073,7 @@ dissect_movechanresponse(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, prot } static int -dissect_movechanconfirmation(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree) +dissect_movechanconfirmation(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) { guint16 icid, result; @@ -1088,7 +1092,7 @@ dissect_movechanconfirmation(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, } static int -dissect_movechanconfirmationresponse(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree) +dissect_movechanconfirmationresponse(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) { guint16 icid; @@ -1101,7 +1105,7 @@ dissect_movechanconfirmationresponse(tvbuff_t *tvb, int offset, packet_info *pin } static int -dissect_connparamrequest(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree) +dissect_connparamrequest(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) { proto_item *item; guint16 max_interval, slave_latency; @@ -1129,7 +1133,7 @@ dissect_connparamrequest(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, prot } static int -dissect_connparamresponse(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree) +dissect_connparamresponse(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) { guint16 result; @@ -1144,9 +1148,10 @@ dissect_connparamresponse(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, pro } static int -dissect_disconnrequestresponse(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree) +dissect_disconnrequestresponse(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree) { - guint16 scid, dcid; + guint16 scid; + guint16 dcid; dcid = tvb_get_letohs(tvb, offset); proto_tree_add_item(tree, hf_btl2cap_dcid, tvb, offset, 2, ENC_LITTLE_ENDIAN); @@ -1158,6 +1163,84 @@ dissect_disconnrequestresponse(tvbuff_t *tvb, int offset, packet_info *pinfo _U_ col_append_fstr(pinfo->cinfo, COL_INFO, " (SCID: 0x%04x, DCID: 0x%04x)", scid, dcid); + if (!pinfo->fd->flags.visited) { + 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 key_scid; + guint32 key_dcid; + bthci_acl_data_t *acl_data = (bthci_acl_data_t *) pinfo->private_data; + + 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_dcid = dcid | ((pinfo->p2p_dir == P2P_DIR_RECV) ? 0x00000000 : 0x80000000); + key_scid = scid | ((pinfo->p2p_dir == P2P_DIR_RECV) ? 0x00000000 : 0x80000000); + + k_interface_id = interface_id; + k_adapter_id = adapter_id; + k_chandle = chandle; + k_cid = key_dcid; + 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 == key_dcid && + psm_data->disconnect_in_frame == G_MAXUINT32) { + psm_data->disconnect_in_frame = pinfo->fd->num; + } + + k_interface_id = interface_id; + k_adapter_id = adapter_id; + k_chandle = chandle; + k_cid = key_scid; + 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 == key_scid && + psm_data->disconnect_in_frame == G_MAXUINT32) { + psm_data->disconnect_in_frame = pinfo->fd->num; + } + } + return offset; } @@ -1815,7 +1898,8 @@ dissect_btl2cap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) psm_data->adapter_id == adapter_id && psm_data->chandle == chandle && (psm_data->scid == key_cid || - psm_data->dcid == key_cid)) { + psm_data->dcid == key_cid) && + psm_data->disconnect_in_frame > pinfo->fd->num) { if ((psm_data->scid == key_cid) && psm_data->first_scid_frame == 0) { |