Bluetooth: Check for waiting HAL callbacks am: a7d33b3636 am: 00802c2adb am: 1a9a9321bc

am: 8b2b644d1b

Change-Id: I01f81cdbe26df58fae38fe400eb31f1416e26246
This commit is contained in:
Myles Watson 2017-01-31 00:39:43 +00:00 committed by android-build-merger
commit 58becfb77c
3 changed files with 35 additions and 11 deletions

View file

@ -42,3 +42,6 @@ const size_t HCI_EVENT_PREAMBLE_SIZE = 2;
const size_t HCI_LENGTH_OFFSET_EVT = 1; const size_t HCI_LENGTH_OFFSET_EVT = 1;
const size_t HCI_PREAMBLE_SIZE_MAX = HCI_ACL_PREAMBLE_SIZE; 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;

View file

@ -40,6 +40,8 @@ using android::hardware::bluetooth::V1_0::implementation::VendorInterface;
using android::hardware::hidl_vec; using android::hardware::hidl_vec;
tINT_CMD_CBACK internal_command_cb; tINT_CMD_CBACK internal_command_cb;
uint16_t internal_command_opcode;
VendorInterface* g_vendor_interface = nullptr; VendorInterface* g_vendor_interface = nullptr;
const size_t preamble_size_for_type[] = { const size_t preamble_size_for_type[] = {
@ -68,9 +70,27 @@ HC_BT_HDR* WrapPacketAndCopy(uint16_t event, const hidl_vec<uint8_t>& data) {
return packet; return packet;
} }
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) { 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_cb = callback;
internal_command_opcode = opcode;
uint8_t type = HCI_PACKET_TYPE_COMMAND; uint8_t type = HCI_PACKET_TYPE_COMMAND;
VendorInterface::get()->Send(&type, 1); VendorInterface::get()->Send(&type, 1);
HC_BT_HDR* bt_hdr = reinterpret_cast<HC_BT_HDR*>(buffer); HC_BT_HDR* bt_hdr = reinterpret_cast<HC_BT_HDR*>(buffer);
@ -281,7 +301,6 @@ size_t VendorInterface::Send(const uint8_t* data, size_t length) {
void VendorInterface::OnFirmwareConfigured(uint8_t result) { void VendorInterface::OnFirmwareConfigured(uint8_t result) {
ALOGD("%s result: %d", __func__, result); ALOGD("%s result: %d", __func__, result);
internal_command_cb = nullptr;
if (firmware_startup_timer_ != nullptr) { if (firmware_startup_timer_ != nullptr) {
delete firmware_startup_timer_; delete firmware_startup_timer_;
@ -341,17 +360,18 @@ void VendorInterface::OnDataReady(int fd) {
hci_packet_bytes_remaining_ -= bytes_read; hci_packet_bytes_remaining_ -= bytes_read;
hci_packet_bytes_read_ += bytes_read; hci_packet_bytes_read_ += bytes_read;
if (hci_packet_bytes_remaining_ == 0) { 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 = HC_BT_HDR* bt_hdr =
WrapPacketAndCopy(HCI_PACKET_TYPE_EVENT, hci_packet_); WrapPacketAndCopy(HCI_PACKET_TYPE_EVENT, hci_packet_);
internal_command_cb(bt_hdr);
} else if (packet_read_cb_ != nullptr && // The callbacks can send new commands, so don't zero after calling.
initialize_complete_cb_ == nullptr) { tINT_CMD_CBACK saved_cb = internal_command_cb;
packet_read_cb_(hci_packet_type_, hci_packet_); internal_command_cb = nullptr;
saved_cb(bt_hdr);
} else { } else {
ALOGE( packet_read_cb_(hci_packet_type_, hci_packet_);
"%s HCI_PAYLOAD received without packet_read_cb or pending init.",
__func__);
} }
hci_parser_state_ = HCI_IDLE; hci_parser_state_ = HCI_IDLE;
} }

View file

@ -49,7 +49,8 @@ class VendorInterface {
private: private:
virtual ~VendorInterface() = default; 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 Close();
void OnDataReady(int fd); void OnDataReady(int fd);