Loading bluetooth/1.0/default/bluetooth_hci.cc +3 −0 Original line number Diff line number Diff line Loading @@ -89,6 +89,9 @@ Return<void> BluetoothHci::initialize( if (!hidl_status.isOk()) { ALOGE("VendorInterface -> Unable to call scoDataReceived()"); } }, [cb](const hidl_vec<uint8_t>&) { ALOGE("VendorInterface -> No callback for ISO packets in HAL V1_0"); }); if (!rc) { auto hidl_status = cb->initializationComplete(Status::INITIALIZATION_ERROR); Loading bluetooth/1.0/default/h4_protocol.cc +3 −0 Original line number Diff line number Diff line Loading @@ -58,6 +58,9 @@ void H4Protocol::OnPacketReady() { case HCI_PACKET_TYPE_SCO_DATA: sco_cb_(hci_packetizer_.GetPacket()); break; case HCI_PACKET_TYPE_ISO_DATA: iso_cb_(hci_packetizer_.GetPacket()); break; default: LOG_ALWAYS_FATAL("%s: Unimplemented packet type %d", __func__, static_cast<int>(hci_packet_type_)); Loading bluetooth/1.0/default/h4_protocol.h +3 −1 Original line number Diff line number Diff line Loading @@ -31,11 +31,12 @@ namespace hci { class H4Protocol : public HciProtocol { public: H4Protocol(int fd, PacketReadCallback event_cb, PacketReadCallback acl_cb, PacketReadCallback sco_cb) PacketReadCallback sco_cb, PacketReadCallback iso_cb) : uart_fd_(fd), event_cb_(event_cb), acl_cb_(acl_cb), sco_cb_(sco_cb), iso_cb_(iso_cb), hci_packetizer_([this]() { OnPacketReady(); }) {} size_t Send(uint8_t type, const uint8_t* data, size_t length); Loading @@ -50,6 +51,7 @@ class H4Protocol : public HciProtocol { PacketReadCallback event_cb_; PacketReadCallback acl_cb_; PacketReadCallback sco_cb_; PacketReadCallback iso_cb_; HciPacketType hci_packet_type_{HCI_PACKET_TYPE_UNKNOWN}; hci::HciPacketizer hci_packetizer_; Loading bluetooth/1.0/default/hci_internals.h +2 −1 Original line number Diff line number Diff line Loading @@ -24,7 +24,8 @@ enum HciPacketType { HCI_PACKET_TYPE_COMMAND = 1, HCI_PACKET_TYPE_ACL_DATA = 2, HCI_PACKET_TYPE_SCO_DATA = 3, HCI_PACKET_TYPE_EVENT = 4 HCI_PACKET_TYPE_EVENT = 4, HCI_PACKET_TYPE_ISO_DATA = 5, }; // 2 bytes for opcode, 1 byte for parameter length (Volume 2, Part E, 5.4.1) Loading bluetooth/1.0/default/test/h4_protocol_unittest.cc +35 −3 Original line number Diff line number Diff line Loading @@ -42,11 +42,15 @@ using ::testing::Eq; static char sample_data1[100] = "A point is that which has no part."; static char sample_data2[100] = "A line is breadthless length."; static char sample_data3[100] = "The ends of a line are points."; static char sample_data4[100] = "A plane surface is a surface which lies evenly with the straight ..."; static char acl_data[100] = "A straight line is a line which lies evenly with the points on itself."; static char sco_data[100] = "A surface is that which has length and breadth only."; static char event_data[100] = "The edges of a surface are lines."; static char iso_data[100] = "A plane angle is the inclination to one another of two lines in a ..."; MATCHER_P3(HidlVecMatches, preamble, preamble_length, payload, "") { size_t length = strlen(payload) + preamble_length; Loading Loading @@ -75,9 +79,9 @@ class H4ProtocolTest : public ::testing::Test { int sockfd[2]; socketpair(AF_LOCAL, SOCK_STREAM, 0, sockfd); H4Protocol* h4_hci = new H4Protocol(sockfd[0], event_cb_.AsStdFunction(), acl_cb_.AsStdFunction(), sco_cb_.AsStdFunction()); H4Protocol* h4_hci = new H4Protocol( sockfd[0], event_cb_.AsStdFunction(), acl_cb_.AsStdFunction(), sco_cb_.AsStdFunction(), iso_cb_.AsStdFunction()); fd_watcher_.WatchFdForNonBlockingReads( sockfd[0], [h4_hci](int fd) { h4_hci->OnDataReady(fd); }); protocol_ = h4_hci; Loading Loading @@ -184,9 +188,35 @@ class H4ProtocolTest : public ::testing::Test { } } void WriteAndExpectInboundIsoData(char* payload) { // h4 type[1] + handle[2] + size[1] char preamble[4] = {HCI_PACKET_TYPE_ISO_DATA, 20, 17, 0}; preamble[3] = strlen(payload) & 0xFF; ALOGD("%s writing", __func__); TEMP_FAILURE_RETRY(write(fake_uart_, preamble, sizeof(preamble))); TEMP_FAILURE_RETRY(write(fake_uart_, payload, strlen(payload))); ALOGD("%s waiting", __func__); std::mutex mutex; std::condition_variable done; EXPECT_CALL(iso_cb_, Call(HidlVecMatches(preamble + 1, sizeof(preamble) - 1, payload))) .WillOnce(Notify(&mutex, &done)); // Fail if it takes longer than 100 ms. auto timeout_time = std::chrono::steady_clock::now() + std::chrono::milliseconds(100); { std::unique_lock<std::mutex> lock(mutex); done.wait_until(lock, timeout_time); } } testing::MockFunction<void(const hidl_vec<uint8_t>&)> event_cb_; testing::MockFunction<void(const hidl_vec<uint8_t>&)> acl_cb_; testing::MockFunction<void(const hidl_vec<uint8_t>&)> sco_cb_; testing::MockFunction<void(const hidl_vec<uint8_t>&)> iso_cb_; async::AsyncFdWatcher fd_watcher_; H4Protocol* protocol_; int fake_uart_; Loading @@ -197,6 +227,7 @@ TEST_F(H4ProtocolTest, TestSends) { SendAndReadUartOutbound(HCI_PACKET_TYPE_COMMAND, sample_data1); SendAndReadUartOutbound(HCI_PACKET_TYPE_ACL_DATA, sample_data2); SendAndReadUartOutbound(HCI_PACKET_TYPE_SCO_DATA, sample_data3); SendAndReadUartOutbound(HCI_PACKET_TYPE_ISO_DATA, sample_data4); } // Ensure we properly parse data coming from the UART Loading @@ -204,6 +235,7 @@ TEST_F(H4ProtocolTest, TestReads) { WriteAndExpectInboundAclData(acl_data); WriteAndExpectInboundScoData(sco_data); WriteAndExpectInboundEvent(event_data); WriteAndExpectInboundIsoData(iso_data); } } // namespace implementation Loading Loading
bluetooth/1.0/default/bluetooth_hci.cc +3 −0 Original line number Diff line number Diff line Loading @@ -89,6 +89,9 @@ Return<void> BluetoothHci::initialize( if (!hidl_status.isOk()) { ALOGE("VendorInterface -> Unable to call scoDataReceived()"); } }, [cb](const hidl_vec<uint8_t>&) { ALOGE("VendorInterface -> No callback for ISO packets in HAL V1_0"); }); if (!rc) { auto hidl_status = cb->initializationComplete(Status::INITIALIZATION_ERROR); Loading
bluetooth/1.0/default/h4_protocol.cc +3 −0 Original line number Diff line number Diff line Loading @@ -58,6 +58,9 @@ void H4Protocol::OnPacketReady() { case HCI_PACKET_TYPE_SCO_DATA: sco_cb_(hci_packetizer_.GetPacket()); break; case HCI_PACKET_TYPE_ISO_DATA: iso_cb_(hci_packetizer_.GetPacket()); break; default: LOG_ALWAYS_FATAL("%s: Unimplemented packet type %d", __func__, static_cast<int>(hci_packet_type_)); Loading
bluetooth/1.0/default/h4_protocol.h +3 −1 Original line number Diff line number Diff line Loading @@ -31,11 +31,12 @@ namespace hci { class H4Protocol : public HciProtocol { public: H4Protocol(int fd, PacketReadCallback event_cb, PacketReadCallback acl_cb, PacketReadCallback sco_cb) PacketReadCallback sco_cb, PacketReadCallback iso_cb) : uart_fd_(fd), event_cb_(event_cb), acl_cb_(acl_cb), sco_cb_(sco_cb), iso_cb_(iso_cb), hci_packetizer_([this]() { OnPacketReady(); }) {} size_t Send(uint8_t type, const uint8_t* data, size_t length); Loading @@ -50,6 +51,7 @@ class H4Protocol : public HciProtocol { PacketReadCallback event_cb_; PacketReadCallback acl_cb_; PacketReadCallback sco_cb_; PacketReadCallback iso_cb_; HciPacketType hci_packet_type_{HCI_PACKET_TYPE_UNKNOWN}; hci::HciPacketizer hci_packetizer_; Loading
bluetooth/1.0/default/hci_internals.h +2 −1 Original line number Diff line number Diff line Loading @@ -24,7 +24,8 @@ enum HciPacketType { HCI_PACKET_TYPE_COMMAND = 1, HCI_PACKET_TYPE_ACL_DATA = 2, HCI_PACKET_TYPE_SCO_DATA = 3, HCI_PACKET_TYPE_EVENT = 4 HCI_PACKET_TYPE_EVENT = 4, HCI_PACKET_TYPE_ISO_DATA = 5, }; // 2 bytes for opcode, 1 byte for parameter length (Volume 2, Part E, 5.4.1) Loading
bluetooth/1.0/default/test/h4_protocol_unittest.cc +35 −3 Original line number Diff line number Diff line Loading @@ -42,11 +42,15 @@ using ::testing::Eq; static char sample_data1[100] = "A point is that which has no part."; static char sample_data2[100] = "A line is breadthless length."; static char sample_data3[100] = "The ends of a line are points."; static char sample_data4[100] = "A plane surface is a surface which lies evenly with the straight ..."; static char acl_data[100] = "A straight line is a line which lies evenly with the points on itself."; static char sco_data[100] = "A surface is that which has length and breadth only."; static char event_data[100] = "The edges of a surface are lines."; static char iso_data[100] = "A plane angle is the inclination to one another of two lines in a ..."; MATCHER_P3(HidlVecMatches, preamble, preamble_length, payload, "") { size_t length = strlen(payload) + preamble_length; Loading Loading @@ -75,9 +79,9 @@ class H4ProtocolTest : public ::testing::Test { int sockfd[2]; socketpair(AF_LOCAL, SOCK_STREAM, 0, sockfd); H4Protocol* h4_hci = new H4Protocol(sockfd[0], event_cb_.AsStdFunction(), acl_cb_.AsStdFunction(), sco_cb_.AsStdFunction()); H4Protocol* h4_hci = new H4Protocol( sockfd[0], event_cb_.AsStdFunction(), acl_cb_.AsStdFunction(), sco_cb_.AsStdFunction(), iso_cb_.AsStdFunction()); fd_watcher_.WatchFdForNonBlockingReads( sockfd[0], [h4_hci](int fd) { h4_hci->OnDataReady(fd); }); protocol_ = h4_hci; Loading Loading @@ -184,9 +188,35 @@ class H4ProtocolTest : public ::testing::Test { } } void WriteAndExpectInboundIsoData(char* payload) { // h4 type[1] + handle[2] + size[1] char preamble[4] = {HCI_PACKET_TYPE_ISO_DATA, 20, 17, 0}; preamble[3] = strlen(payload) & 0xFF; ALOGD("%s writing", __func__); TEMP_FAILURE_RETRY(write(fake_uart_, preamble, sizeof(preamble))); TEMP_FAILURE_RETRY(write(fake_uart_, payload, strlen(payload))); ALOGD("%s waiting", __func__); std::mutex mutex; std::condition_variable done; EXPECT_CALL(iso_cb_, Call(HidlVecMatches(preamble + 1, sizeof(preamble) - 1, payload))) .WillOnce(Notify(&mutex, &done)); // Fail if it takes longer than 100 ms. auto timeout_time = std::chrono::steady_clock::now() + std::chrono::milliseconds(100); { std::unique_lock<std::mutex> lock(mutex); done.wait_until(lock, timeout_time); } } testing::MockFunction<void(const hidl_vec<uint8_t>&)> event_cb_; testing::MockFunction<void(const hidl_vec<uint8_t>&)> acl_cb_; testing::MockFunction<void(const hidl_vec<uint8_t>&)> sco_cb_; testing::MockFunction<void(const hidl_vec<uint8_t>&)> iso_cb_; async::AsyncFdWatcher fd_watcher_; H4Protocol* protocol_; int fake_uart_; Loading @@ -197,6 +227,7 @@ TEST_F(H4ProtocolTest, TestSends) { SendAndReadUartOutbound(HCI_PACKET_TYPE_COMMAND, sample_data1); SendAndReadUartOutbound(HCI_PACKET_TYPE_ACL_DATA, sample_data2); SendAndReadUartOutbound(HCI_PACKET_TYPE_SCO_DATA, sample_data3); SendAndReadUartOutbound(HCI_PACKET_TYPE_ISO_DATA, sample_data4); } // Ensure we properly parse data coming from the UART Loading @@ -204,6 +235,7 @@ TEST_F(H4ProtocolTest, TestReads) { WriteAndExpectInboundAclData(acl_data); WriteAndExpectInboundScoData(sco_data); WriteAndExpectInboundEvent(event_data); WriteAndExpectInboundIsoData(iso_data); } } // namespace implementation Loading