component/bt : fix hci reassemble bug as cf2d19

This commit is contained in:
Yulong
2016-11-12 05:59:07 -05:00
committed by Tian Hao
parent fc6be12a8f
commit 4079d1e008
3 changed files with 37 additions and 21 deletions

View File

@@ -191,14 +191,14 @@ static void hci_hal_h4_hdl_rx_packet(BT_HDR *packet) {
if (type == HCI_BLE_EVENT) { if (type == HCI_BLE_EVENT) {
uint8_t len; uint8_t len;
STREAM_TO_UINT8(len, stream); 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); packet->len, len);
hci_hal_env.allocator->free(packet); hci_hal_env.allocator->free(packet);
return; return;
} }
if (type < DATA_TYPE_ACL || type > DATA_TYPE_EVENT) { if (type < DATA_TYPE_ACL || type > DATA_TYPE_EVENT) {
LOG_ERROR("%s Unknown HCI message type. Dropping this byte 0x%x," LOG_ERROR("%d Unknown HCI message type. Dropping this byte 0x%x,"
" min %x, max %x", __func__, type, " min %x, max %x\n", __func__, type,
DATA_TYPE_ACL, DATA_TYPE_EVENT); DATA_TYPE_ACL, DATA_TYPE_EVENT);
hci_hal_env.allocator->free(packet); hci_hal_env.allocator->free(packet);
return; return;
@@ -211,8 +211,11 @@ static void hci_hal_h4_hdl_rx_packet(BT_HDR *packet) {
return; return;
} }
if (type == DATA_TYPE_ACL) { if (type == DATA_TYPE_ACL) {
packet->offset--;
stream += hdr_size - 2; stream += hdr_size - 2;
STREAM_TO_UINT16(length, stream); STREAM_TO_UINT16(length, stream);
stream = packet->data + 1;
memcpy(packet->data, stream, packet->len);
} else { } else {
stream += hdr_size - 1; stream += hdr_size - 1;
STREAM_TO_UINT8(length, stream); 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_size = BT_HDR_SIZE + len;
pkt = (BT_HDR *)hci_hal_env.allocator->alloc(pkt_size); pkt = (BT_HDR *)hci_hal_env.allocator->alloc(pkt_size);
if (!pkt) { 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; return -1;
} }
pkt->offset = 0; pkt->offset = 0;

View File

@@ -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 // This is kind of a weird case, since we're dispatching a partially sent packet
// up to a higher layer. // up to a higher layer.
// TODO(zachoverflow): rework upper layer so this isn't necessary. // 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); //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) else if (event == MSG_STACK_TO_HC_HCI_CMD)
return DATA_TYPE_COMMAND; return DATA_TYPE_COMMAND;
else 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; return 0;
} }

View File

@@ -41,6 +41,7 @@
// TODO(zachoverflow): find good value for this // TODO(zachoverflow): find good value for this
#define NUMBER_OF_BUCKETS 42 #define NUMBER_OF_BUCKETS 42
uint16_t data_len = 0;
// Our interface and callbacks // Our interface and callbacks
static const packet_fragmenter_t interface; 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) { 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) { 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 handle;
uint16_t l2cap_length; uint16_t l2cap_length;
uint16_t acl_length; uint16_t acl_length;
uint8_t boundary_flag;
BT_HDR *partial_packet;
STREAM_TO_UINT16(handle, stream); STREAM_TO_UINT16(handle, stream);
STREAM_TO_UINT16(acl_length, 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); 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; 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) { if (boundary_flag == START_PACKET_BOUNDARY) {
uint16_t full_length;
if (partial_packet) { 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); 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) {
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); callbacks->reassembled(packet);
return; 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 // Free the old packet buffer, since we don't need it anymore
buffer_allocator->free(packet); buffer_allocator->free(packet);
} else { } else {
uint16_t projected_offset;
if (!partial_packet) { 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); buffer_allocator->free(packet);
return; return;
} }
packet->offset = HCI_ACL_PREAMBLE_SIZE; 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 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; packet->len = partial_packet->len - partial_packet->offset;
projected_offset = partial_packet->len; projected_offset = partial_packet->len;
} }
@@ -198,8 +203,15 @@ static void reassemble_and_dispatch(BT_HDR *packet) {
partial_packet->offset = projected_offset; partial_packet->offset = projected_offset;
if (partial_packet->offset == partial_packet->len) { 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); hash_map_erase(partial_packets, (void *)(uintptr_t)handle);
partial_packet->offset = 0; partial_packet->offset = 0;
callbacks->reassembled(partial_packet); callbacks->reassembled(partial_packet);
} }
} }