Merge "wifi: Fixing Nits"
diff --git a/bluetooth/1.0/default/bluetooth_hci.cc b/bluetooth/1.0/default/bluetooth_hci.cc
index 1559119..6cea623 100644
--- a/bluetooth/1.0/default/bluetooth_hci.cc
+++ b/bluetooth/1.0/default/bluetooth_hci.cc
@@ -83,8 +83,7 @@
 
 void BluetoothHci::sendDataToController(const uint8_t type,
                                         const hidl_vec<uint8_t>& data) {
-  VendorInterface::get()->Send(&type, 1);
-  VendorInterface::get()->Send(data.data(), data.size());
+  VendorInterface::get()->Send(type, data.data(), data.size());
 }
 
 IBluetoothHci* HIDL_FETCH_IBluetoothHci(const char* /* name */) {
diff --git a/bluetooth/1.0/default/hci_internals.h b/bluetooth/1.0/default/hci_internals.h
index d839590..d5714be 100644
--- a/bluetooth/1.0/default/hci_internals.h
+++ b/bluetooth/1.0/default/hci_internals.h
@@ -42,3 +42,6 @@
 const size_t HCI_LENGTH_OFFSET_EVT = 1;
 
 const size_t HCI_PREAMBLE_SIZE_MAX = HCI_ACL_PREAMBLE_SIZE;
+
+// Event codes (Volume 2, Part E, 7.7.14)
+const uint8_t HCI_COMMAND_COMPLETE_EVENT = 0x0E;
diff --git a/bluetooth/1.0/default/vendor_interface.cc b/bluetooth/1.0/default/vendor_interface.cc
index 5f1c33f..51a0add 100644
--- a/bluetooth/1.0/default/vendor_interface.cc
+++ b/bluetooth/1.0/default/vendor_interface.cc
@@ -40,6 +40,8 @@
 using android::hardware::hidl_vec;
 
 tINT_CMD_CBACK internal_command_cb;
+uint16_t internal_command_opcode;
+
 VendorInterface* g_vendor_interface = nullptr;
 
 const size_t preamble_size_for_type[] = {
@@ -49,11 +51,10 @@
     0, HCI_LENGTH_OFFSET_CMD, HCI_LENGTH_OFFSET_ACL, HCI_LENGTH_OFFSET_SCO,
     HCI_LENGTH_OFFSET_EVT};
 
-size_t HciGetPacketLengthForType(HciPacketType type,
-                                 const hidl_vec<uint8_t>& packet) {
+size_t HciGetPacketLengthForType(HciPacketType type, const uint8_t* preamble) {
   size_t offset = packet_length_offset_for_type[type];
-  if (type != HCI_PACKET_TYPE_ACL_DATA) return packet[offset];
-  return (((packet[offset + 1]) << 8) | packet[offset]);
+  if (type != HCI_PACKET_TYPE_ACL_DATA) return preamble[offset];
+  return (((preamble[offset + 1]) << 8) | preamble[offset]);
 }
 
 HC_BT_HDR* WrapPacketAndCopy(uint16_t event, const hidl_vec<uint8_t>& data) {
@@ -69,13 +70,54 @@
   return packet;
 }
 
+size_t write_safely(int fd, const uint8_t* data, size_t length) {
+  size_t transmitted_length = 0;
+  while (length > 0) {
+    ssize_t ret =
+        TEMP_FAILURE_RETRY(write(fd, data + transmitted_length, length));
+
+    if (ret == -1) {
+      if (errno == EAGAIN) continue;
+      ALOGE("%s error writing to UART (%s)", __func__, strerror(errno));
+      break;
+
+    } else if (ret == 0) {
+      // Nothing written :(
+      ALOGE("%s zero bytes written - something went wrong...", __func__);
+      break;
+    }
+
+    transmitted_length += ret;
+    length -= ret;
+  }
+
+  return transmitted_length;
+}
+
+bool internal_command_event_match(const hidl_vec<uint8_t>& packet) {
+  uint8_t event_code = packet[0];
+  if (event_code != HCI_COMMAND_COMPLETE_EVENT) {
+    ALOGE("%s: Unhandled event type %02X", __func__, event_code);
+    return false;
+  }
+
+  size_t opcode_offset = HCI_EVENT_PREAMBLE_SIZE + 1;  // Skip num packets.
+
+  uint16_t opcode = packet[opcode_offset] | (packet[opcode_offset + 1] << 8);
+
+  ALOGV("%s internal_command_opcode = %04X opcode = %04x", __func__,
+        internal_command_opcode, opcode);
+  return opcode == internal_command_opcode;
+}
+
 uint8_t transmit_cb(uint16_t opcode, void* buffer, tINT_CMD_CBACK callback) {
-  ALOGV("%s opcode: 0x%04x, ptr: %p", __func__, opcode, buffer);
+  ALOGV("%s opcode: 0x%04x, ptr: %p, cb: %p", __func__, opcode, buffer,
+        callback);
   internal_command_cb = callback;
+  internal_command_opcode = opcode;
   uint8_t type = HCI_PACKET_TYPE_COMMAND;
-  VendorInterface::get()->Send(&type, 1);
   HC_BT_HDR* bt_hdr = reinterpret_cast<HC_BT_HDR*>(buffer);
-  VendorInterface::get()->Send(bt_hdr->data, bt_hdr->len);
+  VendorInterface::get()->Send(type, bt_hdr->data, bt_hdr->len);
   return true;
 }
 
@@ -139,7 +181,7 @@
         std::chrono::steady_clock::now() - start_time_;
     double s = duration.count();
     if (s == 0) return;
-    ALOGD("Firmware configured in %.3fs", s);
+    ALOGI("Firmware configured in %.3fs", s);
   }
 
  private:
@@ -221,7 +263,7 @@
     return false;
   }
 
-  ALOGD("%s UART fd: %d", __func__, uart_fd_);
+  ALOGI("%s UART fd: %d", __func__, uart_fd_);
 
   fd_watcher_.WatchFdForNonBlockingReads(uart_fd_,
                                          [this](int fd) { OnDataReady(fd); });
@@ -254,35 +296,18 @@
   }
 }
 
-size_t VendorInterface::Send(const uint8_t* data, size_t length) {
+size_t VendorInterface::Send(uint8_t type, const uint8_t* data, size_t length) {
   if (uart_fd_ == INVALID_FD) return 0;
 
-  size_t transmitted_length = 0;
-  while (length > 0) {
-    ssize_t ret =
-        TEMP_FAILURE_RETRY(write(uart_fd_, data + transmitted_length, length));
+  int rv = write_safely(uart_fd_, &type, sizeof(type));
+  if (rv == sizeof(type))
+    rv = write_safely(uart_fd_, data, length);
 
-    if (ret == -1) {
-      if (errno == EAGAIN) continue;
-      ALOGE("%s error writing to UART (%s)", __func__, strerror(errno));
-      break;
-
-    } else if (ret == 0) {
-      // Nothing written :(
-      ALOGE("%s zero bytes written - something went wrong...", __func__);
-      break;
-    }
-
-    transmitted_length += ret;
-    length -= ret;
-  }
-
-  return transmitted_length;
+  return rv;
 }
 
 void VendorInterface::OnFirmwareConfigured(uint8_t result) {
   ALOGD("%s result: %d", __func__, result);
-  internal_command_cb = nullptr;
 
   if (firmware_startup_timer_ != nullptr) {
     delete firmware_startup_timer_;
@@ -305,9 +330,8 @@
       // TODO(eisenbach): Check for workaround(s)
       CHECK(hci_packet_type_ >= HCI_PACKET_TYPE_ACL_DATA &&
             hci_packet_type_ <= HCI_PACKET_TYPE_EVENT)
-          << "buffer[0] = " << buffer[0];
+          << "buffer[0] = " << static_cast<unsigned int>(buffer[0]);
       hci_parser_state_ = HCI_TYPE_READY;
-      hci_packet_.resize(HCI_PREAMBLE_SIZE_MAX);
       hci_packet_bytes_remaining_ = preamble_size_for_type[hci_packet_type_];
       hci_packet_bytes_read_ = 0;
       break;
@@ -315,16 +339,18 @@
 
     case HCI_TYPE_READY: {
       size_t bytes_read = TEMP_FAILURE_RETRY(
-          read(fd, hci_packet_.data() + hci_packet_bytes_read_,
+          read(fd, hci_packet_preamble_ + hci_packet_bytes_read_,
                hci_packet_bytes_remaining_));
       CHECK(bytes_read > 0);
       hci_packet_bytes_remaining_ -= bytes_read;
       hci_packet_bytes_read_ += bytes_read;
       if (hci_packet_bytes_remaining_ == 0) {
         size_t packet_length =
-            HciGetPacketLengthForType(hci_packet_type_, hci_packet_);
+            HciGetPacketLengthForType(hci_packet_type_, hci_packet_preamble_);
         hci_packet_.resize(preamble_size_for_type[hci_packet_type_] +
                            packet_length);
+        memcpy(hci_packet_.data(), hci_packet_preamble_,
+               preamble_size_for_type[hci_packet_type_]);
         hci_packet_bytes_remaining_ = packet_length;
         hci_parser_state_ = HCI_PAYLOAD;
         hci_packet_bytes_read_ = 0;
@@ -341,17 +367,18 @@
       hci_packet_bytes_remaining_ -= bytes_read;
       hci_packet_bytes_read_ += bytes_read;
       if (hci_packet_bytes_remaining_ == 0) {
-        if (internal_command_cb != nullptr) {
+        if (internal_command_cb != nullptr &&
+            hci_packet_type_ == HCI_PACKET_TYPE_EVENT &&
+            internal_command_event_match(hci_packet_)) {
           HC_BT_HDR* bt_hdr =
               WrapPacketAndCopy(HCI_PACKET_TYPE_EVENT, hci_packet_);
-          internal_command_cb(bt_hdr);
-        } else if (packet_read_cb_ != nullptr &&
-                   initialize_complete_cb_ == nullptr) {
-          packet_read_cb_(hci_packet_type_, hci_packet_);
+
+          // The callbacks can send new commands, so don't zero after calling.
+          tINT_CMD_CBACK saved_cb = internal_command_cb;
+          internal_command_cb = nullptr;
+          saved_cb(bt_hdr);
         } else {
-          ALOGE(
-              "%s HCI_PAYLOAD received without packet_read_cb or pending init.",
-              __func__);
+          packet_read_cb_(hci_packet_type_, hci_packet_);
         }
         hci_parser_state_ = HCI_IDLE;
       }
diff --git a/bluetooth/1.0/default/vendor_interface.h b/bluetooth/1.0/default/vendor_interface.h
index 450b99c..79611cd 100644
--- a/bluetooth/1.0/default/vendor_interface.h
+++ b/bluetooth/1.0/default/vendor_interface.h
@@ -42,14 +42,15 @@
   static void Shutdown();
   static VendorInterface *get();
 
-  size_t Send(const uint8_t *data, size_t length);
+  size_t Send(uint8_t type, const uint8_t *data, size_t length);
 
   void OnFirmwareConfigured(uint8_t result);
 
  private:
   virtual ~VendorInterface() = default;
 
-  bool Open(InitializeCompleteCallback initialize_complete_cb, PacketReadCallback packet_read_cb);
+  bool Open(InitializeCompleteCallback initialize_complete_cb,
+            PacketReadCallback packet_read_cb);
   void Close();
 
   void OnDataReady(int fd);
@@ -64,6 +65,7 @@
   enum HciParserState { HCI_IDLE, HCI_TYPE_READY, HCI_PAYLOAD };
   HciParserState hci_parser_state_{HCI_IDLE};
   HciPacketType hci_packet_type_{HCI_PACKET_TYPE_UNKNOWN};
+  uint8_t hci_packet_preamble_[HCI_PREAMBLE_SIZE_MAX];
   hidl_vec<uint8_t> hci_packet_;
   size_t hci_packet_bytes_remaining_;
   size_t hci_packet_bytes_read_;