From 4079d1e008afd89128e4d2d0152e6a3432148ec5 Mon Sep 17 00:00:00 2001 From: Yulong Date: Sat, 12 Nov 2016 05:59:07 -0500 Subject: [PATCH] component/bt : fix hci reassemble bug as cf2d19 --- components/bt/bluedroid/hci/hci_hal_h4.c | 11 +++-- components/bt/bluedroid/hci/hci_layer.c | 5 ++- .../bt/bluedroid/hci/packet_fragmenter.c | 42 ++++++++++++------- 3 files changed, 37 insertions(+), 21 deletions(-) diff --git a/components/bt/bluedroid/hci/hci_hal_h4.c b/components/bt/bluedroid/hci/hci_hal_h4.c index 07bdbdf966..743ccdcdcc 100755 --- a/components/bt/bluedroid/hci/hci_hal_h4.c +++ b/components/bt/bluedroid/hci/hci_hal_h4.c @@ -191,14 +191,14 @@ static void hci_hal_h4_hdl_rx_packet(BT_HDR *packet) { if (type == HCI_BLE_EVENT) { uint8_t len; STREAM_TO_UINT8(len, stream); - LOG_ERROR("Workround stream corrupted during LE SCAN: pkt_len=%d ble_event_len=%d", + LOG_ERROR("Workround stream corrupted during LE SCAN: pkt_len=%d ble_event_len=%d\n", packet->len, len); hci_hal_env.allocator->free(packet); return; } if (type < DATA_TYPE_ACL || type > DATA_TYPE_EVENT) { - LOG_ERROR("%s Unknown HCI message type. Dropping this byte 0x%x," - " min %x, max %x", __func__, type, + LOG_ERROR("%d Unknown HCI message type. Dropping this byte 0x%x," + " min %x, max %x\n", __func__, type, DATA_TYPE_ACL, DATA_TYPE_EVENT); hci_hal_env.allocator->free(packet); return; @@ -211,8 +211,11 @@ static void hci_hal_h4_hdl_rx_packet(BT_HDR *packet) { return; } if (type == DATA_TYPE_ACL) { + packet->offset--; stream += hdr_size - 2; STREAM_TO_UINT16(length, stream); + stream = packet->data + 1; + memcpy(packet->data, stream, packet->len); } else { stream += hdr_size - 1; STREAM_TO_UINT8(length, stream); @@ -251,7 +254,7 @@ static int host_recv_pkt_cb(uint8_t *data, uint16_t len) { pkt_size = BT_HDR_SIZE + len; pkt = (BT_HDR *)hci_hal_env.allocator->alloc(pkt_size); if (!pkt) { - LOG_ERROR("%s couldn't aquire memory for inbound data buffer.", __func__); + LOG_ERROR("%s couldn't aquire memory for inbound data buffer.\n", __func__); return -1; } pkt->offset = 0; diff --git a/components/bt/bluedroid/hci/hci_layer.c b/components/bt/bluedroid/hci/hci_layer.c index cc9a0ab84e..5b8f4de5c0 100755 --- a/components/bt/bluedroid/hci/hci_layer.c +++ b/components/bt/bluedroid/hci/hci_layer.c @@ -369,7 +369,8 @@ static void fragmenter_transmit_finished(BT_HDR *packet, bool all_fragments_sent // This is kind of a weird case, since we're dispatching a partially sent packet // up to a higher layer. // TODO(zachoverflow): rework upper layer so this isn't necessary. - dispatch_reassembled(packet); + buffer_allocator->free(packet); + //dispatch_reassembled(packet); //data_dispatcher_dispatch(interface.event_dispatcher, packet->event & MSG_EVT_MASK, packet); } } @@ -531,7 +532,7 @@ static serial_data_type_t event_to_data_type(uint16_t event) { else if (event == MSG_STACK_TO_HC_HCI_CMD) return DATA_TYPE_COMMAND; else - LOG_ERROR("%s invalid event type, could not translate 0x%x", __func__, event); + LOG_ERROR("%s invalid event type, could not translate 0x%x\n", __func__, event); return 0; } diff --git a/components/bt/bluedroid/hci/packet_fragmenter.c b/components/bt/bluedroid/hci/packet_fragmenter.c index 675f222869..540df2d7ba 100755 --- a/components/bt/bluedroid/hci/packet_fragmenter.c +++ b/components/bt/bluedroid/hci/packet_fragmenter.c @@ -41,6 +41,7 @@ // TODO(zachoverflow): find good value for this #define NUMBER_OF_BUCKETS 42 +uint16_t data_len = 0; // Our interface and callbacks static const packet_fragmenter_t interface; @@ -119,13 +120,12 @@ static void fragment_and_dispatch(BT_HDR *packet) { } static void reassemble_and_dispatch(BT_HDR *packet) { + LOG_ERROR("reassemble_and_dispatch\n"); if ((packet->event & MSG_EVT_MASK) == MSG_HC_TO_STACK_HCI_ACL) { - uint8_t *stream = packet->data + packet->offset; + uint8_t *stream = packet->data; uint16_t handle; uint16_t l2cap_length; uint16_t acl_length; - uint8_t boundary_flag; - BT_HDR *partial_packet; STREAM_TO_UINT16(handle, stream); STREAM_TO_UINT16(acl_length, stream); @@ -133,24 +133,30 @@ static void reassemble_and_dispatch(BT_HDR *packet) { assert(acl_length == packet->len - HCI_ACL_PREAMBLE_SIZE); - boundary_flag = GET_BOUNDARY_FLAG(handle); + uint8_t boundary_flag = GET_BOUNDARY_FLAG(handle); handle = handle & HANDLE_MASK; - partial_packet = (BT_HDR *)hash_map_get(partial_packets, (void *)(uintptr_t)handle); + BT_HDR *partial_packet = (BT_HDR *)hash_map_get(partial_packets, (void *)(uintptr_t)handle); if (boundary_flag == START_PACKET_BOUNDARY) { - uint16_t full_length; if (partial_packet) { - LOG_WARN("%s found unfinished packet for handle with start packet. Dropping old.", __func__); - + LOG_ERROR("%s found unfinished packet for handle with start packet. Dropping old.\n", __func__); + LOG_ERROR("partial_packet->len = %x, offset = %x\n",partial_packet->len,partial_packet->len); + + for (int i = 0; i < partial_packet->len; i++) + { + LOG_ERROR("%x",partial_packet->data[i]); + } + LOG_ERROR("\n"); hash_map_erase(partial_packets, (void *)(uintptr_t)handle); - buffer_allocator->free(partial_packet); + //buffer_allocator->free(partial_packet); + LOG_ERROR("+++++++++++++++++++\n"); } - full_length = l2cap_length + L2CAP_HEADER_SIZE + HCI_ACL_PREAMBLE_SIZE; + uint16_t full_length = l2cap_length + L2CAP_HEADER_SIZE + HCI_ACL_PREAMBLE_SIZE; if (full_length <= packet->len) { if (full_length < packet->len) - LOG_WARN("%s found l2cap full length %d less than the hci length %d.", __func__, l2cap_length, packet->len); + LOG_WARN("%s found l2cap full length %d less than the hci length %d.\n", __func__, l2cap_length, packet->len); callbacks->reassembled(packet); return; @@ -172,17 +178,16 @@ static void reassemble_and_dispatch(BT_HDR *packet) { // Free the old packet buffer, since we don't need it anymore buffer_allocator->free(packet); } else { - uint16_t projected_offset; if (!partial_packet) { - LOG_WARN("%s got continuation for unknown packet. Dropping it.", __func__); + LOG_ERROR("%s got continuation for unknown packet. Dropping it.\n", __func__); buffer_allocator->free(packet); return; } packet->offset = HCI_ACL_PREAMBLE_SIZE; - projected_offset = partial_packet->offset + (packet->len - HCI_ACL_PREAMBLE_SIZE); + uint16_t projected_offset = partial_packet->offset + (packet->len - HCI_ACL_PREAMBLE_SIZE); if (projected_offset > partial_packet->len) { // len stores the expected length - LOG_WARN("%s got packet which would exceed expected length of %d. Truncating.", __func__, partial_packet->len); + LOG_ERROR("%s got packet which would exceed expected length of %d. Truncating.\n", __func__, partial_packet->len); packet->len = partial_packet->len - partial_packet->offset; projected_offset = partial_packet->len; } @@ -198,8 +203,15 @@ static void reassemble_and_dispatch(BT_HDR *packet) { partial_packet->offset = projected_offset; if (partial_packet->offset == partial_packet->len) { + stream = partial_packet->data; + STREAM_TO_UINT16(handle, stream); + STREAM_TO_UINT16(acl_length, stream); + STREAM_TO_UINT16(l2cap_length, stream); + LOG_ERROR("partial_packet->offset = %x\n",partial_packet->offset); hash_map_erase(partial_packets, (void *)(uintptr_t)handle); partial_packet->offset = 0; + + callbacks->reassembled(partial_packet); } } -- 2.40.0