]> granicus.if.org Git - esp-idf/commitdiff
component/bt : fix hci reassemble bug as cf2d19
authorYulong <huangyulong@espressif.com>
Sat, 12 Nov 2016 10:59:07 +0000 (05:59 -0500)
committerTian Hao <tianhao@espressif.com>
Mon, 21 Nov 2016 07:11:34 +0000 (15:11 +0800)
components/bt/bluedroid/hci/hci_hal_h4.c
components/bt/bluedroid/hci/hci_layer.c
components/bt/bluedroid/hci/packet_fragmenter.c

index 07bdbdf9669d8d64730703acb9e15a8353553f6e..743ccdcdccf09959818eec3bfe7e00423cb79e13 100755 (executable)
@@ -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;
index cc9a0ab84e281319955a07adc0b710fa64690f04..5b8f4de5c03ff10c64e857083f7f1198165f2416 100755 (executable)
@@ -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;
 }
index 675f222869d4145675d239385419830c9dc875cb..540df2d7ba9e341e15000bd706860341d379055b 100755 (executable)
@@ -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);
       }
     }