forked from osmocom/wireshark
[BTLE] Dissect LE Information frame.
Change-Id: Id4411526eef895fc0130108457866892216d5b03 Reviewed-on: https://code.wireshark.org/review/16958 Petri-Dish: Anders Broman <a.broman58@gmail.com> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Anders Broman <a.broman58@gmail.com>
This commit is contained in:
parent
ffbb822b88
commit
57fb1abaa5
|
@ -31,6 +31,7 @@ typedef struct _bthci_acl_data_t {
|
|||
|
||||
guint32 remote_bd_addr_oui;
|
||||
guint32 remote_bd_addr_id;
|
||||
gboolean is_btle;
|
||||
} bthci_acl_data_t;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -161,6 +161,23 @@ static dissector_table_t l2cap_cid_dissector_table;
|
|||
*/
|
||||
static wmem_tree_t *cid_to_psm_table = NULL;
|
||||
|
||||
/* 5.4 RETRANSMISSION AND FLOW CONTROL OPTION
|
||||
* Table 5.2
|
||||
* Mode
|
||||
* 0x00 L2CAP Basic Mode
|
||||
* 0x01 Retransmission mode
|
||||
* 0x02 Flow control mode
|
||||
* 0x03 Enhanced Retransmission mode
|
||||
* 0x04 Streaming mode
|
||||
* Other values Reserved for future use
|
||||
*/
|
||||
|
||||
#define L2CAP_BASIC_MODE 0
|
||||
/* XXX Cheat and define a vaue for
|
||||
* Connection-Oriented Channels in LE Credit Based Flow Control Mode
|
||||
*/
|
||||
#define L2CAP_LE_CREDIT_BASED_FLOW_CONTROL_MODE 0xff
|
||||
|
||||
typedef struct _config_data_t {
|
||||
guint8 mode;
|
||||
guint8 txwindow;
|
||||
|
@ -743,6 +760,261 @@ dissect_connrequest(tvbuff_t *tvb, int offset, packet_info *pinfo,
|
|||
|
||||
return offset;
|
||||
}
|
||||
static int
|
||||
dissect_le_credit_based_connrequest(tvbuff_t *tvb, int offset, packet_info *pinfo,
|
||||
proto_tree *tree, proto_tree *command_tree, gboolean is_ch_request _U_,
|
||||
bthci_acl_data_t *acl_data, btl2cap_data_t *l2cap_data)
|
||||
{
|
||||
|
||||
proto_item *psm_item;
|
||||
guint32 psm;
|
||||
guint32 scid;
|
||||
|
||||
|
||||
proto_tree_add_item_ret_uint(command_tree, hf_btl2cap_le_psm, tvb, offset, 2, ENC_LITTLE_ENDIAN, &psm);
|
||||
if (psm < 0x80) {
|
||||
psm_item = proto_tree_add_item(command_tree, hf_btl2cap_psm, tvb, offset, 2, ENC_LITTLE_ENDIAN);
|
||||
PROTO_ITEM_SET_GENERATED(psm_item);
|
||||
}
|
||||
offset += 2;
|
||||
|
||||
proto_tree_add_item_ret_uint(command_tree, hf_btl2cap_scid, tvb, offset, 2, ENC_LITTLE_ENDIAN, &scid);
|
||||
offset += 2;
|
||||
|
||||
proto_tree_add_item(command_tree, hf_btl2cap_option_mtu, tvb, offset, 2, ENC_LITTLE_ENDIAN);
|
||||
offset += 2;
|
||||
|
||||
proto_tree_add_item(command_tree, hf_btl2cap_option_mps, tvb, offset, 2, ENC_LITTLE_ENDIAN);
|
||||
offset += 2;
|
||||
|
||||
proto_tree_add_item(command_tree, hf_btl2cap_initial_credits, tvb, offset, 2, ENC_LITTLE_ENDIAN);
|
||||
offset += 2;
|
||||
|
||||
if (!pinfo->fd->flags.visited) {
|
||||
wmem_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;
|
||||
psm_data_t *psm_data;
|
||||
|
||||
if (pinfo->phdr->presence_flags & WTAP_HAS_INTERFACE_ID)
|
||||
interface_id = pinfo->phdr->interface_id;
|
||||
else
|
||||
interface_id = HCI_INTERFACE_DEFAULT;
|
||||
adapter_id = (acl_data) ? acl_data->adapter_id : HCI_ADAPTER_DEFAULT;
|
||||
chandle = (acl_data) ? acl_data->chandle : 0;
|
||||
|
||||
k_interface_id = interface_id;
|
||||
k_adapter_id = adapter_id;
|
||||
k_chandle = chandle;
|
||||
k_cid = scid;
|
||||
k_frame_number = pinfo->num;
|
||||
|
||||
psm_data = wmem_new(wmem_file_scope(), psm_data_t);
|
||||
|
||||
psm_data->local_cid = scid;
|
||||
psm_data->remote_cid = BTL2CAP_UNKNOWN_CID;
|
||||
|
||||
psm_data->psm = psm;
|
||||
psm_data->local_service = (pinfo->p2p_dir == P2P_DIR_RECV) ? TRUE : FALSE;
|
||||
psm_data->in.mode = L2CAP_LE_CREDIT_BASED_FLOW_CONTROL_MODE;
|
||||
psm_data->in.txwindow = 0;
|
||||
psm_data->in.start_fragments = wmem_tree_new(wmem_file_scope());
|
||||
psm_data->out.mode = L2CAP_LE_CREDIT_BASED_FLOW_CONTROL_MODE;
|
||||
psm_data->out.txwindow = 0;
|
||||
psm_data->out.start_fragments = wmem_tree_new(wmem_file_scope());
|
||||
psm_data->interface_id = k_interface_id;
|
||||
psm_data->adapter_id = k_adapter_id;
|
||||
psm_data->chandle = k_chandle;
|
||||
psm_data->connect_in_frame = pinfo->num;
|
||||
psm_data->disconnect_in_frame = max_disconnect_in_frame;
|
||||
|
||||
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;
|
||||
|
||||
wmem_tree_insert32_array(cid_to_psm_table, key, psm_data);
|
||||
}
|
||||
|
||||
if (l2cap_data) {
|
||||
proto_item *sub_item;
|
||||
guint32 bt_uuid = 0;
|
||||
guint32 disconnect_in_frame = 0;
|
||||
psm_data_t *psm_data;
|
||||
wmem_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;
|
||||
|
||||
if (pinfo->phdr->presence_flags & WTAP_HAS_INTERFACE_ID)
|
||||
interface_id = pinfo->phdr->interface_id;
|
||||
else
|
||||
interface_id = HCI_INTERFACE_DEFAULT;
|
||||
adapter_id = (acl_data) ? acl_data->adapter_id : HCI_ADAPTER_DEFAULT;
|
||||
chandle = (acl_data) ? acl_data->chandle : 0;
|
||||
|
||||
k_interface_id = interface_id;
|
||||
k_adapter_id = adapter_id;
|
||||
k_chandle = chandle;
|
||||
k_cid = scid;
|
||||
k_frame_number = pinfo->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 = (psm_data_t *)wmem_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->local_cid == k_cid) {
|
||||
bt_uuid = get_service_uuid(pinfo, l2cap_data, psm_data->psm, psm_data->local_service);
|
||||
disconnect_in_frame = psm_data->disconnect_in_frame;
|
||||
}
|
||||
|
||||
if (bt_uuid) {
|
||||
sub_item = proto_tree_add_uint(tree, hf_btl2cap_service, tvb, 0, 0, bt_uuid);
|
||||
PROTO_ITEM_SET_GENERATED(sub_item);
|
||||
}
|
||||
|
||||
if (disconnect_in_frame < max_disconnect_in_frame) {
|
||||
sub_item = proto_tree_add_uint(tree, hf_btl2cap_disconnect_in_frame, tvb, 0, 0, disconnect_in_frame);
|
||||
PROTO_ITEM_SET_GENERATED(sub_item);
|
||||
}
|
||||
}
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
static int
|
||||
dissect_le_credit_based_connresponse(tvbuff_t *tvb, int offset, packet_info *pinfo,
|
||||
proto_tree *tree, bthci_acl_data_t *acl_data)
|
||||
{
|
||||
guint32 dcid;
|
||||
|
||||
proto_tree_add_item_ret_uint(tree, hf_btl2cap_dcid, tvb, offset, 2, ENC_LITTLE_ENDIAN, &dcid);
|
||||
offset += 2;
|
||||
|
||||
proto_tree_add_item(tree, hf_btl2cap_option_mtu, tvb, offset, 2, ENC_LITTLE_ENDIAN);
|
||||
offset += 2;
|
||||
|
||||
proto_tree_add_item(tree, hf_btl2cap_option_mps, tvb, offset, 2, ENC_LITTLE_ENDIAN);
|
||||
offset += 2;
|
||||
|
||||
proto_tree_add_item(tree, hf_btl2cap_initial_credits, tvb, offset, 2, ENC_LITTLE_ENDIAN);
|
||||
offset += 2;
|
||||
|
||||
proto_tree_add_item(tree, hf_btl2cap_le_result, tvb, offset, 2, ENC_LITTLE_ENDIAN);
|
||||
offset += 2;
|
||||
|
||||
|
||||
if (pinfo->fd->flags.visited == 0) {
|
||||
psm_data_t *psm_data;
|
||||
wmem_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;
|
||||
|
||||
if (pinfo->phdr->presence_flags & WTAP_HAS_INTERFACE_ID)
|
||||
interface_id = pinfo->phdr->interface_id;
|
||||
else
|
||||
interface_id = HCI_INTERFACE_DEFAULT;
|
||||
adapter_id = (acl_data) ? acl_data->adapter_id : HCI_ADAPTER_DEFAULT;
|
||||
chandle = (acl_data) ? acl_data->chandle : 0;
|
||||
cid = dcid;
|
||||
|
||||
k_interface_id = interface_id;
|
||||
k_adapter_id = adapter_id;
|
||||
k_chandle = chandle;
|
||||
k_cid = cid;
|
||||
k_frame_number = pinfo->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 = (psm_data_t *)wmem_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 &&
|
||||
((pinfo->p2p_dir == P2P_DIR_SENT && psm_data->remote_cid == cid) ||
|
||||
(pinfo->p2p_dir == P2P_DIR_RECV && psm_data->local_cid == cid)) &&
|
||||
psm_data->disconnect_in_frame > pinfo->num) {
|
||||
cid = dcid | 0x80000000;
|
||||
|
||||
k_interface_id = interface_id;
|
||||
k_adapter_id = adapter_id;
|
||||
k_chandle = chandle;
|
||||
k_cid = cid;
|
||||
k_frame_number = pinfo->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;
|
||||
|
||||
if (pinfo->p2p_dir == P2P_DIR_RECV)
|
||||
psm_data->remote_cid = cid;
|
||||
else
|
||||
psm_data->local_cid = cid;
|
||||
|
||||
wmem_tree_insert32_array(cid_to_psm_table, key, psm_data);
|
||||
}
|
||||
}
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
static int
|
||||
dissect_movechanrequest(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
|
||||
|
@ -772,7 +1044,7 @@ dissect_options(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *t
|
|||
guint8 option_type, option_length;
|
||||
|
||||
if (config_data) {
|
||||
config_data->mode = 0;
|
||||
config_data->mode = L2CAP_BASIC_MODE;
|
||||
config_data->txwindow = 0;
|
||||
}
|
||||
|
||||
|
@ -1660,6 +1932,74 @@ dissect_b_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
|
|||
return offset;
|
||||
}
|
||||
|
||||
/* FIX ME, Basicly a copy of the code above, needs to be fixed.*/
|
||||
static int
|
||||
dissect_le_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
|
||||
proto_tree *btl2cap_tree, guint16 cid, guint16 psm,
|
||||
gboolean is_local_psm, guint16 length, int offset, btl2cap_data_t *l2cap_data)
|
||||
{
|
||||
|
||||
tvbuff_t *next_tvb;
|
||||
/* FIX ME reassembly needed*/
|
||||
next_tvb = tvb_new_subset(tvb, offset, tvb_captured_length_remaining(tvb, offset), length);
|
||||
|
||||
col_append_str(pinfo->cinfo, COL_INFO, "Connection oriented channel, LE Information frame");
|
||||
|
||||
if (psm) {
|
||||
proto_item *psm_item;
|
||||
guint16 bt_uuid;
|
||||
bluetooth_uuid_t uuid;
|
||||
|
||||
if (p_get_proto_data(pinfo->pool, pinfo, proto_btl2cap, PROTO_DATA_BTL2CAP_PSM) == NULL) {
|
||||
guint16 *value_data;
|
||||
|
||||
value_data = wmem_new(wmem_file_scope(), guint16);
|
||||
*value_data = psm;
|
||||
|
||||
p_add_proto_data(pinfo->pool, pinfo, proto_btl2cap, PROTO_DATA_BTL2CAP_PSM, value_data);
|
||||
}
|
||||
|
||||
bt_uuid = get_service_uuid(pinfo, l2cap_data, psm, is_local_psm);
|
||||
|
||||
uuid.size = 2;
|
||||
uuid.bt_uuid = bt_uuid;
|
||||
uuid.data[0] = bt_uuid >> 8;
|
||||
uuid.data[1] = bt_uuid & 0xFF;
|
||||
|
||||
if (bt_uuid && p_get_proto_data(pinfo->pool, pinfo, proto_bluetooth, PROTO_DATA_BLUETOOTH_SERVICE_UUID) == NULL) {
|
||||
guint8 *value_data;
|
||||
|
||||
value_data = wmem_strdup(wmem_file_scope(), print_numeric_uuid(&uuid));
|
||||
|
||||
p_add_proto_data(pinfo->pool, pinfo, proto_bluetooth, PROTO_DATA_BLUETOOTH_SERVICE_UUID, value_data);
|
||||
}
|
||||
|
||||
if (psm < BTL2CAP_DYNAMIC_PSM_START) {
|
||||
psm_item = proto_tree_add_uint(btl2cap_tree, hf_btl2cap_psm, tvb, offset, 0, psm);
|
||||
}
|
||||
else {
|
||||
psm_item = proto_tree_add_uint(btl2cap_tree, hf_btl2cap_psm_dynamic, tvb, offset, 0, psm);
|
||||
if (uuid.bt_uuid)
|
||||
proto_item_append_text(psm_item, ": %s",
|
||||
val_to_str_ext_const(uuid.bt_uuid, &bluetooth_uuid_vals_ext, "Unknown service"));
|
||||
}
|
||||
PROTO_ITEM_SET_GENERATED(psm_item);
|
||||
|
||||
/* call next dissector */
|
||||
proto_tree_add_item(btl2cap_tree, hf_btl2cap_payload, tvb, offset, length, ENC_NA);
|
||||
|
||||
/* Fix reassembly and stuff */
|
||||
offset = tvb_captured_length(tvb);
|
||||
}
|
||||
else {
|
||||
if (!dissector_try_uint_new(l2cap_cid_dissector_table, (guint32)cid, next_tvb, pinfo, tree, TRUE, l2cap_data))
|
||||
proto_tree_add_item(btl2cap_tree, hf_btl2cap_payload, tvb, offset, length, ENC_NA);
|
||||
offset = tvb_captured_length(tvb);
|
||||
}
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
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,
|
||||
|
@ -1895,15 +2235,20 @@ dissect_btl2cap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
|
|||
psm_data_t *psm_data;
|
||||
bthci_acl_data_t *acl_data;
|
||||
btl2cap_data_t *l2cap_data;
|
||||
gboolean dir_in_col = TRUE;
|
||||
|
||||
acl_data = (bthci_acl_data_t *) data;
|
||||
|
||||
if ((acl_data) && (acl_data->is_btle)) {
|
||||
dir_in_col = FALSE;
|
||||
}
|
||||
ti = proto_tree_add_item(tree, proto_btl2cap, tvb, offset, -1, ENC_NA);
|
||||
btl2cap_tree = proto_item_add_subtree(ti, ett_btl2cap);
|
||||
|
||||
col_set_str(pinfo->cinfo, COL_PROTOCOL, "L2CAP");
|
||||
|
||||
switch (pinfo->p2p_dir) {
|
||||
if (dir_in_col) {
|
||||
switch (pinfo->p2p_dir) {
|
||||
case P2P_DIR_SENT:
|
||||
col_set_str(pinfo->cinfo, COL_INFO, "Sent ");
|
||||
break;
|
||||
|
@ -1913,6 +2258,9 @@ dissect_btl2cap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
|
|||
default:
|
||||
col_set_str(pinfo->cinfo, COL_INFO, "UnknownDirection ");
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
col_clear(pinfo->cinfo, COL_INFO);
|
||||
}
|
||||
|
||||
length = tvb_get_letohs(tvb, offset);
|
||||
|
@ -2079,37 +2427,11 @@ dissect_btl2cap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
|
|||
break;
|
||||
|
||||
case 0x14: /* LE Credit Based Connection Request */
|
||||
proto_tree_add_item(btl2cap_cmd_tree, hf_btl2cap_le_psm, tvb, offset, 2, ENC_LITTLE_ENDIAN);
|
||||
offset += 2;
|
||||
|
||||
proto_tree_add_item(btl2cap_cmd_tree, hf_btl2cap_scid, tvb, offset, 2, ENC_LITTLE_ENDIAN);
|
||||
offset += 2;
|
||||
|
||||
proto_tree_add_item(btl2cap_cmd_tree, hf_btl2cap_option_mtu, tvb, offset, 2, ENC_LITTLE_ENDIAN);
|
||||
offset += 2;
|
||||
|
||||
proto_tree_add_item(btl2cap_cmd_tree, hf_btl2cap_option_mps, tvb, offset, 2, ENC_LITTLE_ENDIAN);
|
||||
offset += 2;
|
||||
|
||||
proto_tree_add_item(btl2cap_cmd_tree, hf_btl2cap_initial_credits, tvb, offset, 2, ENC_LITTLE_ENDIAN);
|
||||
offset += 2;
|
||||
offset = dissect_le_credit_based_connrequest(tvb, offset, pinfo, btl2cap_tree, btl2cap_cmd_tree, TRUE, acl_data, l2cap_data);
|
||||
break;
|
||||
|
||||
case 0x15: /* LE Credit Based Connection Response */
|
||||
proto_tree_add_item(btl2cap_cmd_tree, hf_btl2cap_dcid, tvb, offset, 2, ENC_LITTLE_ENDIAN);
|
||||
offset += 2;
|
||||
|
||||
proto_tree_add_item(btl2cap_cmd_tree, hf_btl2cap_option_mtu, tvb, offset, 2, ENC_LITTLE_ENDIAN);
|
||||
offset += 2;
|
||||
|
||||
proto_tree_add_item(btl2cap_cmd_tree, hf_btl2cap_option_mps, tvb, offset, 2, ENC_LITTLE_ENDIAN);
|
||||
offset += 2;
|
||||
|
||||
proto_tree_add_item(btl2cap_cmd_tree, hf_btl2cap_initial_credits, tvb, offset, 2, ENC_LITTLE_ENDIAN);
|
||||
offset += 2;
|
||||
|
||||
proto_tree_add_item(btl2cap_cmd_tree, hf_btl2cap_le_result, tvb, offset, 2, ENC_LITTLE_ENDIAN);
|
||||
offset += 2;
|
||||
offset = dissect_le_credit_based_connresponse(tvb, offset, pinfo, btl2cap_cmd_tree, acl_data);
|
||||
break;
|
||||
|
||||
case 0x16: /* LE Flow Control Credit */
|
||||
|
@ -2302,8 +2624,10 @@ dissect_btl2cap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
|
|||
PROTO_ITEM_SET_GENERATED(sub_item);
|
||||
}
|
||||
|
||||
if (config_data->mode == 0) {
|
||||
if (config_data->mode == L2CAP_BASIC_MODE) {
|
||||
offset = dissect_b_frame(tvb, pinfo, tree, btl2cap_tree, cid, psm, psm_data->local_service, length, offset, l2cap_data);
|
||||
}else if (config_data->mode == L2CAP_LE_CREDIT_BASED_FLOW_CONTROL_MODE){
|
||||
offset = dissect_le_frame(tvb, pinfo, tree, btl2cap_tree, cid, psm, psm_data->local_service, length, offset, l2cap_data);
|
||||
} else {
|
||||
control = tvb_get_letohs(tvb, offset);
|
||||
if (control & 0x1) {
|
||||
|
|
|
@ -876,7 +876,6 @@ dissect_btle(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
|
|||
|
||||
if (new_tvb) {
|
||||
bthci_acl_data_t *acl_data;
|
||||
gint saved_p2p_dir;
|
||||
|
||||
col_set_str(pinfo->cinfo, COL_INFO, "L2CAP Data");
|
||||
|
||||
|
@ -886,19 +885,13 @@ dissect_btle(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
|
|||
acl_data->chandle = 0; /* No connection handle at this layer */
|
||||
acl_data->remote_bd_addr_oui = 0;
|
||||
acl_data->remote_bd_addr_id = 0;
|
||||
|
||||
saved_p2p_dir = pinfo->p2p_dir;
|
||||
pinfo->p2p_dir = P2P_DIR_UNKNOWN;
|
||||
acl_data->is_btle = TRUE;
|
||||
|
||||
next_tvb = tvb_new_subset_length(tvb, offset, length);
|
||||
if(next_tvb){
|
||||
call_dissector_with_data(btl2cap_handle, new_tvb, pinfo, tree, acl_data);
|
||||
}
|
||||
offset += length;
|
||||
|
||||
pinfo->p2p_dir = saved_p2p_dir;
|
||||
|
||||
|
||||
}
|
||||
else {
|
||||
col_set_str(pinfo->cinfo, COL_INFO, "L2CAP Fragment");
|
||||
|
@ -947,7 +940,6 @@ dissect_btle(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
|
|||
offset += length;
|
||||
} else {
|
||||
bthci_acl_data_t *acl_data;
|
||||
gint saved_p2p_dir;
|
||||
|
||||
col_set_str(pinfo->cinfo, COL_INFO, "L2CAP Data");
|
||||
|
||||
|
@ -957,15 +949,11 @@ dissect_btle(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
|
|||
acl_data->chandle = 0; /* No connection handle at this layer */
|
||||
acl_data->remote_bd_addr_oui = 0;
|
||||
acl_data->remote_bd_addr_id = 0;
|
||||
|
||||
saved_p2p_dir = pinfo->p2p_dir;
|
||||
pinfo->p2p_dir = P2P_DIR_UNKNOWN;
|
||||
acl_data->is_btle = TRUE;
|
||||
|
||||
next_tvb = tvb_new_subset_length(tvb, offset, length);
|
||||
call_dissector_with_data(btl2cap_handle, next_tvb, pinfo, tree, acl_data);
|
||||
offset += length;
|
||||
|
||||
pinfo->p2p_dir = saved_p2p_dir;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue