Loading system/test/rootcanal/Android.bp +2 −2 Original line number Diff line number Diff line Loading @@ -45,7 +45,7 @@ cc_binary { "android.hardware.bluetooth-async", "android.hardware.bluetooth-hci", "libbt-rootcanal", "libbluetooth-types", "libbt-rootcanal-types", ], include_dirs: [ "packages/modules/Bluetooth/system", Loading Loading @@ -82,10 +82,10 @@ cc_library_shared { "-DHAS_NO_BDROID_BUILDCFG", ], static_libs: [ "libbluetooth-types", "android.hardware.bluetooth-async", "android.hardware.bluetooth-hci", "libbt-rootcanal", "libbt-rootcanal-types", ], include_dirs: [ "packages/modules/Bluetooth/system", Loading system/test/rootcanal/bluetooth_hci.cc +141 −86 Original line number Diff line number Diff line Loading @@ -20,13 +20,12 @@ #include <base/logging.h> #include <cutils/properties.h> #include <netdb.h> #include <netinet/in.h> #include <string.h> #include <utils/Log.h> #include "acl_packet.h" #include "event_packet.h" #include "hci_internals.h" #include "sco_packet.h" namespace android { namespace hardware { Loading @@ -35,15 +34,9 @@ namespace V1_0 { namespace sim { using android::hardware::hidl_vec; using test_vendor_lib::AclPacket; using test_vendor_lib::AsyncManager; using test_vendor_lib::AsyncTaskId; using test_vendor_lib::CommandPacket; using test_vendor_lib::DualModeController; using test_vendor_lib::EventPacket; using test_vendor_lib::ScoPacket; using test_vendor_lib::TaskCallback; using test_vendor_lib::TestChannelTransport; namespace { Loading @@ -58,23 +51,24 @@ class BluetoothDeathRecipient : public hidl_death_recipient { public: BluetoothDeathRecipient(const sp<IBluetoothHci> hci) : mHci(hci) {} virtual void serviceDied( uint64_t /* cookie */, const wp<::android::hidl::base::V1_0::IBase>& /* who */) { virtual void serviceDied(uint64_t /* cookie */, const wp<::android::hidl::base::V1_0::IBase>& /* who */) { ALOGE("BluetoothDeathRecipient::serviceDied - Bluetooth service died"); has_died_ = true; mHci->close(); } sp<IBluetoothHci> mHci; bool getHasDied() const { return has_died_; } void setHasDied(bool has_died) { has_died_ = has_died; } bool getHasDied() const { return has_died_; } void setHasDied(bool has_died) { has_died_ = has_died; } private: bool has_died_; }; BluetoothHci::BluetoothHci() : death_recipient_(new BluetoothDeathRecipient(this)) {} BluetoothHci::BluetoothHci() : death_recipient_(new BluetoothDeathRecipient(this)) {} Return<void> BluetoothHci::initialize(const sp<IBluetoothHciCallbacks>& cb) { ALOGI("%s", __func__); Loading @@ -87,62 +81,50 @@ Return<void> BluetoothHci::initialize(const sp<IBluetoothHciCallbacks>& cb) { death_recipient_->setHasDied(false); cb->linkToDeath(death_recipient_, 0); test_channel_transport_.RegisterCommandHandler( [this](const std::string& name, const std::vector<std::string>& args) { async_manager_.ExecAsync( std::chrono::milliseconds(0), [this, name, args]() { controller_.HandleTestChannelCommand(name, args); }); test_channel_transport_.RegisterCommandHandler([this](const std::string& name, const std::vector<std::string>& args) { async_manager_.ExecAsync(std::chrono::milliseconds(0), [this, name, args]() { test_channel_.HandleCommand(name, args); }); }); controller_.RegisterEventChannel([cb](std::unique_ptr<EventPacket> event) { size_t header_bytes = event->GetHeaderSize(); size_t payload_bytes = event->GetPayloadSize(); hidl_vec<uint8_t> hci_event; hci_event.resize(header_bytes + payload_bytes); memcpy(hci_event.data(), event->GetHeader().data(), header_bytes); memcpy(hci_event.data() + header_bytes, event->GetPayload().data(), payload_bytes); controller_ = std::make_shared<DualModeController>(); controller_->Initialize({"dmc", "3C:5A:B4:01:02:03"}); controller_->RegisterEventChannel([cb](std::shared_ptr<std::vector<uint8_t>> packet) { hidl_vec<uint8_t> hci_event(packet->begin(), packet->end()); cb->hciEventReceived(hci_event); }); controller_.RegisterAclChannel([cb](std::unique_ptr<AclPacket> packet) { std::vector<uint8_t> acl_vector = packet->GetPacket(); hidl_vec<uint8_t> acl_packet = acl_vector; controller_->RegisterAclChannel([cb](std::shared_ptr<std::vector<uint8_t>> packet) { hidl_vec<uint8_t> acl_packet(packet->begin(), packet->end()); cb->aclDataReceived(acl_packet); }); controller_.RegisterScoChannel([cb](std::unique_ptr<ScoPacket> packet) { size_t header_bytes = packet->GetHeaderSize(); size_t payload_bytes = packet->GetPayloadSize(); hidl_vec<uint8_t> sco_packet; sco_packet.resize(header_bytes + payload_bytes); memcpy(sco_packet.data(), packet->GetHeader().data(), header_bytes); memcpy(sco_packet.data() + header_bytes, packet->GetPayload().data(), payload_bytes); cb->scoDataReceived(sco_packet); controller_->RegisterScoChannel([cb](std::shared_ptr<std::vector<uint8_t>> packet) { hidl_vec<uint8_t> sco_packet(packet->begin(), packet->end()); cb->aclDataReceived(sco_packet); }); controller_.RegisterTaskScheduler( [this](std::chrono::milliseconds delay, const TaskCallback& task) { controller_->RegisterTaskScheduler([this](std::chrono::milliseconds delay, const TaskCallback& task) { return async_manager_.ExecAsync(delay, task); }); controller_.RegisterPeriodicTaskScheduler( [this](std::chrono::milliseconds delay, std::chrono::milliseconds period, const TaskCallback& task) { controller_->RegisterPeriodicTaskScheduler( [this](std::chrono::milliseconds delay, std::chrono::milliseconds period, const TaskCallback& task) { return async_manager_.ExecAsyncPeriodically(delay, period, task); }); controller_.RegisterTaskCancel( [this](AsyncTaskId task) { async_manager_.CancelAsyncTask(task); }); controller_->RegisterTaskCancel([this](AsyncTaskId task) { async_manager_.CancelAsyncTask(task); }); test_model_.Reset(); // Add the controller as a device in the model. test_model_.Add(controller_); if (BtTestConsoleEnabled()) { SetUpTestChannel(6111); } SetUpHciServer(6211, [this](int fd) { test_model_.IncomingHciConnection(fd); }); SetUpLinkLayerServer(6311, [this](int fd) { test_model_.IncomingLinkLayerConnection(fd); }); unlink_cb_ = [cb](sp<BluetoothDeathRecipient>& death_recipient) { if (death_recipient->getHasDied()) Loading @@ -162,53 +144,124 @@ Return<void> BluetoothHci::close() { Return<void> BluetoothHci::sendHciCommand(const hidl_vec<uint8_t>& packet) { async_manager_.ExecAsync(std::chrono::milliseconds(0), [this, packet]() { uint16_t opcode = packet[0] | (packet[1] << 8); std::unique_ptr<CommandPacket> command = std::unique_ptr<CommandPacket>(new CommandPacket(opcode)); for (size_t i = 3; i < packet.size(); i++) command->AddPayloadOctets1(packet[i]); controller_.HandleCommand(std::move(command)); std::shared_ptr<std::vector<uint8_t>> packet_copy = std::shared_ptr<std::vector<uint8_t>>(new std::vector<uint8_t>(packet)); controller_->HandleCommand(packet_copy); }); return Void(); } Return<void> BluetoothHci::sendAclData(const hidl_vec<uint8_t>& packet) { async_manager_.ExecAsync(std::chrono::milliseconds(0), [this, packet]() { uint16_t channel = (packet[0] | (packet[1] << 8)) & 0xfff; AclPacket::PacketBoundaryFlags boundary_flags = static_cast<AclPacket::PacketBoundaryFlags>((packet[1] & 0x30) >> 4); AclPacket::BroadcastFlags broadcast_flags = static_cast<AclPacket::BroadcastFlags>((packet[1] & 0xC0) >> 6); std::unique_ptr<AclPacket> acl = std::unique_ptr<AclPacket>( new AclPacket(channel, boundary_flags, broadcast_flags)); for (size_t i = 4; i < packet.size(); i++) acl->AddPayloadOctets1(packet[i]); controller_.HandleAcl(std::move(acl)); std::shared_ptr<std::vector<uint8_t>> packet_copy = std::shared_ptr<std::vector<uint8_t>>(new std::vector<uint8_t>(packet)); controller_->HandleAcl(packet_copy); }); return Void(); } Return<void> BluetoothHci::sendScoData(const hidl_vec<uint8_t>& packet) { async_manager_.ExecAsync(std::chrono::milliseconds(0), [this, packet]() { uint16_t channel = (packet[0] | (packet[1] << 8)) & 0xfff; ScoPacket::PacketStatusFlags packet_status = static_cast<ScoPacket::PacketStatusFlags>((packet[1] & 0x30) >> 4); std::unique_ptr<ScoPacket> sco = std::unique_ptr<ScoPacket>(new ScoPacket(channel, packet_status)); for (size_t i = 3; i < packet.size(); i++) sco->AddPayloadOctets1(packet[i]); controller_.HandleSco(std::move(sco)); std::shared_ptr<std::vector<uint8_t>> packet_copy = std::shared_ptr<std::vector<uint8_t>>(new std::vector<uint8_t>(packet)); controller_->HandleSco(packet_copy); }); return Void(); } void BluetoothHci::SetUpHciServer(int port, const std::function<void(int)>& connection_callback) { int socket_fd = remote_hci_transport_.SetUp(port); test_channel_.RegisterSendResponse( [](const std::string& response) { ALOGI("No HCI Response channel: %s", response.c_str()); }); if (socket_fd == -1) { ALOGE("Remote HCI channel SetUp(%d) failed.", port); return; } async_manager_.WatchFdForNonBlockingReads(socket_fd, [this, connection_callback](int socket_fd) { int conn_fd = remote_hci_transport_.Accept(socket_fd); if (conn_fd < 0) { ALOGE("Error watching remote HCI channel fd."); return; } int flags = fcntl(conn_fd, F_GETFL, NULL); int ret; ret = fcntl(conn_fd, F_SETFL, flags | O_NONBLOCK); CHECK(ret != -1) << "Error setting O_NONBLOCK " << strerror(errno); connection_callback(conn_fd); }); } void BluetoothHci::SetUpLinkLayerServer(int port, const std::function<void(int)>& connection_callback) { int socket_fd = remote_link_layer_transport_.SetUp(port); test_channel_.RegisterSendResponse( [](const std::string& response) { ALOGI("No LinkLayer Response channel: %s", response.c_str()); }); if (socket_fd == -1) { ALOGE("Remote LinkLayer channel SetUp(%d) failed.", port); return; } async_manager_.WatchFdForNonBlockingReads(socket_fd, [this, connection_callback](int socket_fd) { int conn_fd = remote_link_layer_transport_.Accept(socket_fd); if (conn_fd < 0) { ALOGE("Error watching remote LinkLayer channel fd."); return; } int flags = fcntl(conn_fd, F_GETFL, NULL); int ret = fcntl(conn_fd, F_SETFL, flags | O_NONBLOCK); CHECK(ret != -1) << "Error setting O_NONBLOCK " << strerror(errno); connection_callback(conn_fd); }); } int BluetoothHci::ConnectToRemoteServer(const std::string& server, int port) { int socket_fd = socket(AF_INET, SOCK_STREAM, 0); if (socket_fd < 1) { ALOGI("socket() call failed: %s", strerror(errno)); return -1; } struct hostent* host; host = gethostbyname(server.c_str()); if (host == NULL) { ALOGI("gethostbyname() failed for %s: %s", server.c_str(), strerror(errno)); return -1; } struct sockaddr_in serv_addr; memset((void*)&serv_addr, 0, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = INADDR_ANY; serv_addr.sin_port = htons(port); int result = connect(socket_fd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)); if (result < 0) { ALOGI("connect() failed for %s@%d: %s", server.c_str(), port, strerror(errno)); return -1; } int flags = fcntl(socket_fd, F_GETFL, NULL); int ret = fcntl(socket_fd, F_SETFL, flags | O_NONBLOCK); CHECK(ret != -1) << "Error setting O_NONBLOCK " << strerror(errno); return socket_fd; } void BluetoothHci::SetUpTestChannel(int port) { int socket_fd = test_channel_transport_.SetUp(port); test_channel_.RegisterSendResponse( [](const std::string& response) { ALOGI("No test channel: %s", response.c_str()); }); // Add some default devices for easier debugging test_channel_.AddDefaults(); if (socket_fd == -1) { ALOGE("Test channel SetUp(%d) failed.", port); return; Loading @@ -222,10 +275,12 @@ void BluetoothHci::SetUpTestChannel(int port) { return; } ALOGI("Test channel connection accepted."); test_channel_.RegisterSendResponse( [this, conn_fd](const std::string& response) { test_channel_transport_.SendResponse(conn_fd, response); }); async_manager_.WatchFdForNonBlockingReads(conn_fd, [this](int conn_fd) { test_channel_transport_.OnCommandReady(conn_fd, [this, conn_fd]() { async_manager_.StopWatchingFileDescriptor(conn_fd); }); test_channel_transport_.OnCommandReady(conn_fd, [this, conn_fd]() { async_manager_.StopWatchingFileDescriptor(conn_fd); }); }); }); } Loading @@ -235,7 +290,7 @@ IBluetoothHci* HIDL_FETCH_IBluetoothHci(const char* /* name */) { return new BluetoothHci(); } } // namespace gce } // namespace sim } // namespace V1_0 } // namespace bluetooth } // namespace hardware Loading system/test/rootcanal/bluetooth_hci.h +31 −12 Original line number Diff line number Diff line Loading @@ -22,9 +22,11 @@ #include "hci_packetizer.h" #include "async_manager.h" #include "dual_mode_controller.h" #include "test_channel_transport.h" #include "model/controller/dual_mode_controller.h" #include "model/setup/async_manager.h" #include "model/setup/test_channel_transport.h" #include "model/setup/test_command_handler.h" #include "model/setup/test_model.h" namespace android { namespace hardware { Loading @@ -38,17 +40,13 @@ class BluetoothHci : public IBluetoothHci { public: BluetoothHci(); ::android::hardware::Return<void> initialize( const sp<IBluetoothHciCallbacks>& cb) override; ::android::hardware::Return<void> initialize(const sp<IBluetoothHciCallbacks>& cb) override; ::android::hardware::Return<void> sendHciCommand( const ::android::hardware::hidl_vec<uint8_t>& packet) override; ::android::hardware::Return<void> sendHciCommand(const ::android::hardware::hidl_vec<uint8_t>& packet) override; ::android::hardware::Return<void> sendAclData( const ::android::hardware::hidl_vec<uint8_t>& packet) override; ::android::hardware::Return<void> sendAclData(const ::android::hardware::hidl_vec<uint8_t>& packet) override; ::android::hardware::Return<void> sendScoData( const ::android::hardware::hidl_vec<uint8_t>& packet) override; ::android::hardware::Return<void> sendScoData(const ::android::hardware::hidl_vec<uint8_t>& packet) override; ::android::hardware::Return<void> close() override; Loading @@ -66,10 +64,31 @@ class BluetoothHci : public IBluetoothHci { test_vendor_lib::AsyncManager async_manager_; void SetUpTestChannel(int port); void SetUpHciServer(int port, const std::function<void(int)>& on_connect); void SetUpLinkLayerServer(int port, const std::function<void(int)>& on_connect); int ConnectToRemoteServer(const std::string& server, int port); test_vendor_lib::DualModeController controller_; std::shared_ptr<test_vendor_lib::DualModeController> controller_; test_vendor_lib::TestChannelTransport test_channel_transport_; test_vendor_lib::TestChannelTransport remote_hci_transport_; test_vendor_lib::TestChannelTransport remote_link_layer_transport_; test_vendor_lib::TestModel test_model_{ [this](std::chrono::milliseconds delay, const test_vendor_lib::TaskCallback& task) { return async_manager_.ExecAsync(delay, task); }, [this](std::chrono::milliseconds delay, std::chrono::milliseconds period, const test_vendor_lib::TaskCallback& task) { return async_manager_.ExecAsyncPeriodically(delay, period, task); }, [this](test_vendor_lib::AsyncTaskId task) { async_manager_.CancelAsyncTask(task); }, [this](const std::string& server, int port) { return ConnectToRemoteServer(server, port); }}; test_vendor_lib::TestCommandHandler test_channel_{test_model_}; }; extern "C" IBluetoothHci* HIDL_FETCH_IBluetoothHci(const char* name); Loading system/test/rootcanal/service.cc +2 −2 Original line number Diff line number Diff line Loading @@ -23,11 +23,11 @@ #include "bluetooth_hci.h" using ::android::sp; using ::android::hardware::configureRpcThreadpool; using ::android::hardware::joinRpcThreadpool; using ::android::hardware::bluetooth::V1_0::IBluetoothHci; using ::android::hardware::bluetooth::V1_0::sim::BluetoothHci; using ::android::hardware::joinRpcThreadpool; using ::android::sp; int main(int /* argc */, char** /* argv */) { sp<IBluetoothHci> bluetooth = new BluetoothHci; Loading system/vendor_libs/test_vendor_lib/Android.bp +70 −40 Original line number Diff line number Diff line Loading @@ -3,30 +3,38 @@ cc_library_static { name: "libbt-rootcanal", defaults: ["libchrome_support_defaults"], host_supported: true, proprietary: true, srcs: [ "src/acl_packet.cc", "src/async_manager.cc", "src/beacon.cc", "src/beacon_swarm.cc", "src/broken_adv.cc", "src/bt_address.cc", "src/classic.cc", "src/command_packet.cc", "src/connection.cc", "src/device.cc", "src/device_factory.cc", "src/device_properties.cc", "src/dual_mode_controller.cc", "src/event_packet.cc", "src/hci_packet.cc", "src/keyboard.cc", "src/l2cap_packet.cc", "src/l2cap_sdu.cc", "src/packet.cc", "src/packet_stream.cc", "src/sco_packet.cc", "src/test_channel_transport.cc", "model/controller/acl_connection.cc", "model/controller/acl_connection_handler.cc", "model/controller/dual_mode_controller.cc", "model/controller/link_layer_controller.cc", "model/controller/security_manager.cc", "model/devices/beacon.cc", "model/devices/beacon_swarm.cc", "model/devices/broken_adv.cc", "model/devices/car_kit.cc", "model/devices/classic.cc", "model/devices/device.cc", "model/devices/device_properties.cc", "model/devices/h4_packetizer.cc", "model/devices/h4_protocol.cc", "model/devices/hci_packetizer.cc", "model/devices/hci_protocol.cc", "model/devices/hci_socket_device.cc", "model/devices/keyboard.cc", "model/devices/link_layer_socket_device.cc", "model/devices/loopback.cc", "model/devices/polled_socket.cc", "model/devices/remote_loopback_device.cc", "model/devices/sniffer.cc", "model/setup/async_manager.cc", "model/setup/device_boutique.cc", "model/setup/phy_layer_factory.cc", "model/setup/test_channel_transport.cc", "model/setup/test_command_handler.cc", "model/setup/test_model.cc", ], cflags: [ "-fvisibility=hidden", Loading @@ -53,10 +61,12 @@ cc_library_static { "libbase", "liblog", ], static_libs: [ "libbluetooth-types", whole_static_libs: [ "libbt-rootcanal-packets", ], static_libs: [ "libbt-rootcanal-types", ], } // test-vendor unit tests for host Loading @@ -69,21 +79,9 @@ cc_test_host { "clang_coverage_bin", ], srcs: [ "src/async_manager.cc", "src/bt_address.cc", "src/hci_packet.cc", "src/command_packet.cc", "src/event_packet.cc", "src/packet.cc", "src/packet_stream.cc", "src/l2cap_packet.cc", "src/l2cap_sdu.cc", "test/async_manager_unittest.cc", "test/bt_address_unittest.cc", "test/packet_stream_unittest.cc", "test/iterator_test.cc", "test/l2cap_test.cc", "test/l2cap_sdu_test.cc", "test/security_manager_unittest.cc", "test/link_layer_socket_device_test.cc", ], header_libs: [ "libbluetooth_headers", Loading @@ -101,11 +99,43 @@ cc_test_host { "liblog", ], static_libs: [ "libbluetooth-types", "libbt-rootcanal-packets", "libbt-rootcanal-types", "libbt-rootcanal", ], cflags: [ "-fvisibility=hidden", "-DLOG_NDEBUG=1", ], } // Linux RootCanal Executable // ======================================================== cc_test_host { name: "root-canal", defaults: [ "libchrome_support_defaults", ], srcs: [ "desktop/root_canal_main.cc", "desktop/test_environment.cc", ], header_libs: [ "libbluetooth_headers", ], local_include_dirs: [ "include", ], include_dirs: [ "packages/modules/Bluetooth/system", "packages/modules/Bluetooth/system/utils/include", "packages/modules/Bluetooth/system/hci/include", "packages/modules/Bluetooth/system/stack/include", ], shared_libs: [ "liblog", ], static_libs: [ "libbt-rootcanal-types", "libbt-rootcanal", ], } Loading
system/test/rootcanal/Android.bp +2 −2 Original line number Diff line number Diff line Loading @@ -45,7 +45,7 @@ cc_binary { "android.hardware.bluetooth-async", "android.hardware.bluetooth-hci", "libbt-rootcanal", "libbluetooth-types", "libbt-rootcanal-types", ], include_dirs: [ "packages/modules/Bluetooth/system", Loading Loading @@ -82,10 +82,10 @@ cc_library_shared { "-DHAS_NO_BDROID_BUILDCFG", ], static_libs: [ "libbluetooth-types", "android.hardware.bluetooth-async", "android.hardware.bluetooth-hci", "libbt-rootcanal", "libbt-rootcanal-types", ], include_dirs: [ "packages/modules/Bluetooth/system", Loading
system/test/rootcanal/bluetooth_hci.cc +141 −86 Original line number Diff line number Diff line Loading @@ -20,13 +20,12 @@ #include <base/logging.h> #include <cutils/properties.h> #include <netdb.h> #include <netinet/in.h> #include <string.h> #include <utils/Log.h> #include "acl_packet.h" #include "event_packet.h" #include "hci_internals.h" #include "sco_packet.h" namespace android { namespace hardware { Loading @@ -35,15 +34,9 @@ namespace V1_0 { namespace sim { using android::hardware::hidl_vec; using test_vendor_lib::AclPacket; using test_vendor_lib::AsyncManager; using test_vendor_lib::AsyncTaskId; using test_vendor_lib::CommandPacket; using test_vendor_lib::DualModeController; using test_vendor_lib::EventPacket; using test_vendor_lib::ScoPacket; using test_vendor_lib::TaskCallback; using test_vendor_lib::TestChannelTransport; namespace { Loading @@ -58,23 +51,24 @@ class BluetoothDeathRecipient : public hidl_death_recipient { public: BluetoothDeathRecipient(const sp<IBluetoothHci> hci) : mHci(hci) {} virtual void serviceDied( uint64_t /* cookie */, const wp<::android::hidl::base::V1_0::IBase>& /* who */) { virtual void serviceDied(uint64_t /* cookie */, const wp<::android::hidl::base::V1_0::IBase>& /* who */) { ALOGE("BluetoothDeathRecipient::serviceDied - Bluetooth service died"); has_died_ = true; mHci->close(); } sp<IBluetoothHci> mHci; bool getHasDied() const { return has_died_; } void setHasDied(bool has_died) { has_died_ = has_died; } bool getHasDied() const { return has_died_; } void setHasDied(bool has_died) { has_died_ = has_died; } private: bool has_died_; }; BluetoothHci::BluetoothHci() : death_recipient_(new BluetoothDeathRecipient(this)) {} BluetoothHci::BluetoothHci() : death_recipient_(new BluetoothDeathRecipient(this)) {} Return<void> BluetoothHci::initialize(const sp<IBluetoothHciCallbacks>& cb) { ALOGI("%s", __func__); Loading @@ -87,62 +81,50 @@ Return<void> BluetoothHci::initialize(const sp<IBluetoothHciCallbacks>& cb) { death_recipient_->setHasDied(false); cb->linkToDeath(death_recipient_, 0); test_channel_transport_.RegisterCommandHandler( [this](const std::string& name, const std::vector<std::string>& args) { async_manager_.ExecAsync( std::chrono::milliseconds(0), [this, name, args]() { controller_.HandleTestChannelCommand(name, args); }); test_channel_transport_.RegisterCommandHandler([this](const std::string& name, const std::vector<std::string>& args) { async_manager_.ExecAsync(std::chrono::milliseconds(0), [this, name, args]() { test_channel_.HandleCommand(name, args); }); }); controller_.RegisterEventChannel([cb](std::unique_ptr<EventPacket> event) { size_t header_bytes = event->GetHeaderSize(); size_t payload_bytes = event->GetPayloadSize(); hidl_vec<uint8_t> hci_event; hci_event.resize(header_bytes + payload_bytes); memcpy(hci_event.data(), event->GetHeader().data(), header_bytes); memcpy(hci_event.data() + header_bytes, event->GetPayload().data(), payload_bytes); controller_ = std::make_shared<DualModeController>(); controller_->Initialize({"dmc", "3C:5A:B4:01:02:03"}); controller_->RegisterEventChannel([cb](std::shared_ptr<std::vector<uint8_t>> packet) { hidl_vec<uint8_t> hci_event(packet->begin(), packet->end()); cb->hciEventReceived(hci_event); }); controller_.RegisterAclChannel([cb](std::unique_ptr<AclPacket> packet) { std::vector<uint8_t> acl_vector = packet->GetPacket(); hidl_vec<uint8_t> acl_packet = acl_vector; controller_->RegisterAclChannel([cb](std::shared_ptr<std::vector<uint8_t>> packet) { hidl_vec<uint8_t> acl_packet(packet->begin(), packet->end()); cb->aclDataReceived(acl_packet); }); controller_.RegisterScoChannel([cb](std::unique_ptr<ScoPacket> packet) { size_t header_bytes = packet->GetHeaderSize(); size_t payload_bytes = packet->GetPayloadSize(); hidl_vec<uint8_t> sco_packet; sco_packet.resize(header_bytes + payload_bytes); memcpy(sco_packet.data(), packet->GetHeader().data(), header_bytes); memcpy(sco_packet.data() + header_bytes, packet->GetPayload().data(), payload_bytes); cb->scoDataReceived(sco_packet); controller_->RegisterScoChannel([cb](std::shared_ptr<std::vector<uint8_t>> packet) { hidl_vec<uint8_t> sco_packet(packet->begin(), packet->end()); cb->aclDataReceived(sco_packet); }); controller_.RegisterTaskScheduler( [this](std::chrono::milliseconds delay, const TaskCallback& task) { controller_->RegisterTaskScheduler([this](std::chrono::milliseconds delay, const TaskCallback& task) { return async_manager_.ExecAsync(delay, task); }); controller_.RegisterPeriodicTaskScheduler( [this](std::chrono::milliseconds delay, std::chrono::milliseconds period, const TaskCallback& task) { controller_->RegisterPeriodicTaskScheduler( [this](std::chrono::milliseconds delay, std::chrono::milliseconds period, const TaskCallback& task) { return async_manager_.ExecAsyncPeriodically(delay, period, task); }); controller_.RegisterTaskCancel( [this](AsyncTaskId task) { async_manager_.CancelAsyncTask(task); }); controller_->RegisterTaskCancel([this](AsyncTaskId task) { async_manager_.CancelAsyncTask(task); }); test_model_.Reset(); // Add the controller as a device in the model. test_model_.Add(controller_); if (BtTestConsoleEnabled()) { SetUpTestChannel(6111); } SetUpHciServer(6211, [this](int fd) { test_model_.IncomingHciConnection(fd); }); SetUpLinkLayerServer(6311, [this](int fd) { test_model_.IncomingLinkLayerConnection(fd); }); unlink_cb_ = [cb](sp<BluetoothDeathRecipient>& death_recipient) { if (death_recipient->getHasDied()) Loading @@ -162,53 +144,124 @@ Return<void> BluetoothHci::close() { Return<void> BluetoothHci::sendHciCommand(const hidl_vec<uint8_t>& packet) { async_manager_.ExecAsync(std::chrono::milliseconds(0), [this, packet]() { uint16_t opcode = packet[0] | (packet[1] << 8); std::unique_ptr<CommandPacket> command = std::unique_ptr<CommandPacket>(new CommandPacket(opcode)); for (size_t i = 3; i < packet.size(); i++) command->AddPayloadOctets1(packet[i]); controller_.HandleCommand(std::move(command)); std::shared_ptr<std::vector<uint8_t>> packet_copy = std::shared_ptr<std::vector<uint8_t>>(new std::vector<uint8_t>(packet)); controller_->HandleCommand(packet_copy); }); return Void(); } Return<void> BluetoothHci::sendAclData(const hidl_vec<uint8_t>& packet) { async_manager_.ExecAsync(std::chrono::milliseconds(0), [this, packet]() { uint16_t channel = (packet[0] | (packet[1] << 8)) & 0xfff; AclPacket::PacketBoundaryFlags boundary_flags = static_cast<AclPacket::PacketBoundaryFlags>((packet[1] & 0x30) >> 4); AclPacket::BroadcastFlags broadcast_flags = static_cast<AclPacket::BroadcastFlags>((packet[1] & 0xC0) >> 6); std::unique_ptr<AclPacket> acl = std::unique_ptr<AclPacket>( new AclPacket(channel, boundary_flags, broadcast_flags)); for (size_t i = 4; i < packet.size(); i++) acl->AddPayloadOctets1(packet[i]); controller_.HandleAcl(std::move(acl)); std::shared_ptr<std::vector<uint8_t>> packet_copy = std::shared_ptr<std::vector<uint8_t>>(new std::vector<uint8_t>(packet)); controller_->HandleAcl(packet_copy); }); return Void(); } Return<void> BluetoothHci::sendScoData(const hidl_vec<uint8_t>& packet) { async_manager_.ExecAsync(std::chrono::milliseconds(0), [this, packet]() { uint16_t channel = (packet[0] | (packet[1] << 8)) & 0xfff; ScoPacket::PacketStatusFlags packet_status = static_cast<ScoPacket::PacketStatusFlags>((packet[1] & 0x30) >> 4); std::unique_ptr<ScoPacket> sco = std::unique_ptr<ScoPacket>(new ScoPacket(channel, packet_status)); for (size_t i = 3; i < packet.size(); i++) sco->AddPayloadOctets1(packet[i]); controller_.HandleSco(std::move(sco)); std::shared_ptr<std::vector<uint8_t>> packet_copy = std::shared_ptr<std::vector<uint8_t>>(new std::vector<uint8_t>(packet)); controller_->HandleSco(packet_copy); }); return Void(); } void BluetoothHci::SetUpHciServer(int port, const std::function<void(int)>& connection_callback) { int socket_fd = remote_hci_transport_.SetUp(port); test_channel_.RegisterSendResponse( [](const std::string& response) { ALOGI("No HCI Response channel: %s", response.c_str()); }); if (socket_fd == -1) { ALOGE("Remote HCI channel SetUp(%d) failed.", port); return; } async_manager_.WatchFdForNonBlockingReads(socket_fd, [this, connection_callback](int socket_fd) { int conn_fd = remote_hci_transport_.Accept(socket_fd); if (conn_fd < 0) { ALOGE("Error watching remote HCI channel fd."); return; } int flags = fcntl(conn_fd, F_GETFL, NULL); int ret; ret = fcntl(conn_fd, F_SETFL, flags | O_NONBLOCK); CHECK(ret != -1) << "Error setting O_NONBLOCK " << strerror(errno); connection_callback(conn_fd); }); } void BluetoothHci::SetUpLinkLayerServer(int port, const std::function<void(int)>& connection_callback) { int socket_fd = remote_link_layer_transport_.SetUp(port); test_channel_.RegisterSendResponse( [](const std::string& response) { ALOGI("No LinkLayer Response channel: %s", response.c_str()); }); if (socket_fd == -1) { ALOGE("Remote LinkLayer channel SetUp(%d) failed.", port); return; } async_manager_.WatchFdForNonBlockingReads(socket_fd, [this, connection_callback](int socket_fd) { int conn_fd = remote_link_layer_transport_.Accept(socket_fd); if (conn_fd < 0) { ALOGE("Error watching remote LinkLayer channel fd."); return; } int flags = fcntl(conn_fd, F_GETFL, NULL); int ret = fcntl(conn_fd, F_SETFL, flags | O_NONBLOCK); CHECK(ret != -1) << "Error setting O_NONBLOCK " << strerror(errno); connection_callback(conn_fd); }); } int BluetoothHci::ConnectToRemoteServer(const std::string& server, int port) { int socket_fd = socket(AF_INET, SOCK_STREAM, 0); if (socket_fd < 1) { ALOGI("socket() call failed: %s", strerror(errno)); return -1; } struct hostent* host; host = gethostbyname(server.c_str()); if (host == NULL) { ALOGI("gethostbyname() failed for %s: %s", server.c_str(), strerror(errno)); return -1; } struct sockaddr_in serv_addr; memset((void*)&serv_addr, 0, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = INADDR_ANY; serv_addr.sin_port = htons(port); int result = connect(socket_fd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)); if (result < 0) { ALOGI("connect() failed for %s@%d: %s", server.c_str(), port, strerror(errno)); return -1; } int flags = fcntl(socket_fd, F_GETFL, NULL); int ret = fcntl(socket_fd, F_SETFL, flags | O_NONBLOCK); CHECK(ret != -1) << "Error setting O_NONBLOCK " << strerror(errno); return socket_fd; } void BluetoothHci::SetUpTestChannel(int port) { int socket_fd = test_channel_transport_.SetUp(port); test_channel_.RegisterSendResponse( [](const std::string& response) { ALOGI("No test channel: %s", response.c_str()); }); // Add some default devices for easier debugging test_channel_.AddDefaults(); if (socket_fd == -1) { ALOGE("Test channel SetUp(%d) failed.", port); return; Loading @@ -222,10 +275,12 @@ void BluetoothHci::SetUpTestChannel(int port) { return; } ALOGI("Test channel connection accepted."); test_channel_.RegisterSendResponse( [this, conn_fd](const std::string& response) { test_channel_transport_.SendResponse(conn_fd, response); }); async_manager_.WatchFdForNonBlockingReads(conn_fd, [this](int conn_fd) { test_channel_transport_.OnCommandReady(conn_fd, [this, conn_fd]() { async_manager_.StopWatchingFileDescriptor(conn_fd); }); test_channel_transport_.OnCommandReady(conn_fd, [this, conn_fd]() { async_manager_.StopWatchingFileDescriptor(conn_fd); }); }); }); } Loading @@ -235,7 +290,7 @@ IBluetoothHci* HIDL_FETCH_IBluetoothHci(const char* /* name */) { return new BluetoothHci(); } } // namespace gce } // namespace sim } // namespace V1_0 } // namespace bluetooth } // namespace hardware Loading
system/test/rootcanal/bluetooth_hci.h +31 −12 Original line number Diff line number Diff line Loading @@ -22,9 +22,11 @@ #include "hci_packetizer.h" #include "async_manager.h" #include "dual_mode_controller.h" #include "test_channel_transport.h" #include "model/controller/dual_mode_controller.h" #include "model/setup/async_manager.h" #include "model/setup/test_channel_transport.h" #include "model/setup/test_command_handler.h" #include "model/setup/test_model.h" namespace android { namespace hardware { Loading @@ -38,17 +40,13 @@ class BluetoothHci : public IBluetoothHci { public: BluetoothHci(); ::android::hardware::Return<void> initialize( const sp<IBluetoothHciCallbacks>& cb) override; ::android::hardware::Return<void> initialize(const sp<IBluetoothHciCallbacks>& cb) override; ::android::hardware::Return<void> sendHciCommand( const ::android::hardware::hidl_vec<uint8_t>& packet) override; ::android::hardware::Return<void> sendHciCommand(const ::android::hardware::hidl_vec<uint8_t>& packet) override; ::android::hardware::Return<void> sendAclData( const ::android::hardware::hidl_vec<uint8_t>& packet) override; ::android::hardware::Return<void> sendAclData(const ::android::hardware::hidl_vec<uint8_t>& packet) override; ::android::hardware::Return<void> sendScoData( const ::android::hardware::hidl_vec<uint8_t>& packet) override; ::android::hardware::Return<void> sendScoData(const ::android::hardware::hidl_vec<uint8_t>& packet) override; ::android::hardware::Return<void> close() override; Loading @@ -66,10 +64,31 @@ class BluetoothHci : public IBluetoothHci { test_vendor_lib::AsyncManager async_manager_; void SetUpTestChannel(int port); void SetUpHciServer(int port, const std::function<void(int)>& on_connect); void SetUpLinkLayerServer(int port, const std::function<void(int)>& on_connect); int ConnectToRemoteServer(const std::string& server, int port); test_vendor_lib::DualModeController controller_; std::shared_ptr<test_vendor_lib::DualModeController> controller_; test_vendor_lib::TestChannelTransport test_channel_transport_; test_vendor_lib::TestChannelTransport remote_hci_transport_; test_vendor_lib::TestChannelTransport remote_link_layer_transport_; test_vendor_lib::TestModel test_model_{ [this](std::chrono::milliseconds delay, const test_vendor_lib::TaskCallback& task) { return async_manager_.ExecAsync(delay, task); }, [this](std::chrono::milliseconds delay, std::chrono::milliseconds period, const test_vendor_lib::TaskCallback& task) { return async_manager_.ExecAsyncPeriodically(delay, period, task); }, [this](test_vendor_lib::AsyncTaskId task) { async_manager_.CancelAsyncTask(task); }, [this](const std::string& server, int port) { return ConnectToRemoteServer(server, port); }}; test_vendor_lib::TestCommandHandler test_channel_{test_model_}; }; extern "C" IBluetoothHci* HIDL_FETCH_IBluetoothHci(const char* name); Loading
system/test/rootcanal/service.cc +2 −2 Original line number Diff line number Diff line Loading @@ -23,11 +23,11 @@ #include "bluetooth_hci.h" using ::android::sp; using ::android::hardware::configureRpcThreadpool; using ::android::hardware::joinRpcThreadpool; using ::android::hardware::bluetooth::V1_0::IBluetoothHci; using ::android::hardware::bluetooth::V1_0::sim::BluetoothHci; using ::android::hardware::joinRpcThreadpool; using ::android::sp; int main(int /* argc */, char** /* argv */) { sp<IBluetoothHci> bluetooth = new BluetoothHci; Loading
system/vendor_libs/test_vendor_lib/Android.bp +70 −40 Original line number Diff line number Diff line Loading @@ -3,30 +3,38 @@ cc_library_static { name: "libbt-rootcanal", defaults: ["libchrome_support_defaults"], host_supported: true, proprietary: true, srcs: [ "src/acl_packet.cc", "src/async_manager.cc", "src/beacon.cc", "src/beacon_swarm.cc", "src/broken_adv.cc", "src/bt_address.cc", "src/classic.cc", "src/command_packet.cc", "src/connection.cc", "src/device.cc", "src/device_factory.cc", "src/device_properties.cc", "src/dual_mode_controller.cc", "src/event_packet.cc", "src/hci_packet.cc", "src/keyboard.cc", "src/l2cap_packet.cc", "src/l2cap_sdu.cc", "src/packet.cc", "src/packet_stream.cc", "src/sco_packet.cc", "src/test_channel_transport.cc", "model/controller/acl_connection.cc", "model/controller/acl_connection_handler.cc", "model/controller/dual_mode_controller.cc", "model/controller/link_layer_controller.cc", "model/controller/security_manager.cc", "model/devices/beacon.cc", "model/devices/beacon_swarm.cc", "model/devices/broken_adv.cc", "model/devices/car_kit.cc", "model/devices/classic.cc", "model/devices/device.cc", "model/devices/device_properties.cc", "model/devices/h4_packetizer.cc", "model/devices/h4_protocol.cc", "model/devices/hci_packetizer.cc", "model/devices/hci_protocol.cc", "model/devices/hci_socket_device.cc", "model/devices/keyboard.cc", "model/devices/link_layer_socket_device.cc", "model/devices/loopback.cc", "model/devices/polled_socket.cc", "model/devices/remote_loopback_device.cc", "model/devices/sniffer.cc", "model/setup/async_manager.cc", "model/setup/device_boutique.cc", "model/setup/phy_layer_factory.cc", "model/setup/test_channel_transport.cc", "model/setup/test_command_handler.cc", "model/setup/test_model.cc", ], cflags: [ "-fvisibility=hidden", Loading @@ -53,10 +61,12 @@ cc_library_static { "libbase", "liblog", ], static_libs: [ "libbluetooth-types", whole_static_libs: [ "libbt-rootcanal-packets", ], static_libs: [ "libbt-rootcanal-types", ], } // test-vendor unit tests for host Loading @@ -69,21 +79,9 @@ cc_test_host { "clang_coverage_bin", ], srcs: [ "src/async_manager.cc", "src/bt_address.cc", "src/hci_packet.cc", "src/command_packet.cc", "src/event_packet.cc", "src/packet.cc", "src/packet_stream.cc", "src/l2cap_packet.cc", "src/l2cap_sdu.cc", "test/async_manager_unittest.cc", "test/bt_address_unittest.cc", "test/packet_stream_unittest.cc", "test/iterator_test.cc", "test/l2cap_test.cc", "test/l2cap_sdu_test.cc", "test/security_manager_unittest.cc", "test/link_layer_socket_device_test.cc", ], header_libs: [ "libbluetooth_headers", Loading @@ -101,11 +99,43 @@ cc_test_host { "liblog", ], static_libs: [ "libbluetooth-types", "libbt-rootcanal-packets", "libbt-rootcanal-types", "libbt-rootcanal", ], cflags: [ "-fvisibility=hidden", "-DLOG_NDEBUG=1", ], } // Linux RootCanal Executable // ======================================================== cc_test_host { name: "root-canal", defaults: [ "libchrome_support_defaults", ], srcs: [ "desktop/root_canal_main.cc", "desktop/test_environment.cc", ], header_libs: [ "libbluetooth_headers", ], local_include_dirs: [ "include", ], include_dirs: [ "packages/modules/Bluetooth/system", "packages/modules/Bluetooth/system/utils/include", "packages/modules/Bluetooth/system/hci/include", "packages/modules/Bluetooth/system/stack/include", ], shared_libs: [ "liblog", ], static_libs: [ "libbt-rootcanal-types", "libbt-rootcanal", ], }