Loading system/test/rootcanal/bluetooth_hci.cc +51 −106 Original line number Diff line number Diff line Loading @@ -18,13 +18,13 @@ #include "bluetooth_hci.h" #include "log/log.h" #include <cutils/properties.h> #include <netdb.h> #include <netinet/in.h> #include <string.h> #include "hci_internals.h" #include "log/log.h" namespace android { namespace hardware { Loading Loading @@ -58,18 +58,15 @@ class BluetoothDeathRecipient : public hidl_death_recipient { 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<V1_0::IBluetoothHciCallbacks>& cb) { Loading Loading @@ -104,7 +101,8 @@ Return<void> BluetoothHci::initialize_impl( controller_ = std::make_shared<DualModeController>(); char mac_property[PROPERTY_VALUE_MAX] = ""; property_get("vendor.bt.rootcanal_mac_address", mac_property, "3C:5A:B4:01:02:03"); property_get("vendor.bt.rootcanal_mac_address", mac_property, "3C:5A:B4:01:02:03"); controller_->Initialize({"dmc", std::string(mac_property)}); controller_->RegisterEventChannel( Loading Loading @@ -193,11 +191,25 @@ Return<void> BluetoothHci::initialize_impl( }); if (BtTestConsoleEnabled()) { SetUpTestChannel(6111); SetUpHciServer(6211, [this](int fd) { test_model_.IncomingHciConnection(fd); }); SetUpLinkLayerServer( 6311, [this](int fd) { test_model_.IncomingLinkLayerConnection(fd); }); test_socket_server_ = std::make_shared<net::PosixAsyncSocketServer>(6111, &async_manager_); hci_socket_server_ = std::make_shared<net::PosixAsyncSocketServer>(6211, &async_manager_); link_socket_server_ = std::make_shared<net::PosixAsyncSocketServer>(6311, &async_manager_); connector_ = std::make_shared<net::PosixAsyncSocketConnector>(&async_manager_); SetUpTestChannel(); SetUpHciServer([this](std::shared_ptr<AsyncDataChannel> socket, AsyncDataChannelServer* srv) { test_model_.IncomingHciConnection(socket); srv->StartListening(); }); SetUpLinkLayerServer([this](std::shared_ptr<AsyncDataChannel> socket, AsyncDataChannelServer* srv) { test_model_.IncomingLinkLayerConnection(socket); srv->StartListening(); }); } else { // This should be configurable in the future. LOG_INFO("Adding Beacons so the scan list is not empty."); Loading Loading @@ -283,122 +295,55 @@ Return<void> BluetoothHci::sendIsoData(const hidl_vec<uint8_t>& packet) { return Void(); } void BluetoothHci::SetUpHciServer(int port, const std::function<void(int)>& connection_callback) { int socket_fd = remote_hci_transport_.SetUp(port); void BluetoothHci::SetUpHciServer(ConnectCallback connection_callback) { test_channel_.RegisterSendResponse([](const std::string& response) { LOG_INFO("No HCI Response channel: %s", response.c_str()); }); if (socket_fd == -1) { LOG_ERROR("Remote HCI channel SetUp(%d) failed.", port); if (!remote_hci_transport_.SetUp(hci_socket_server_, connection_callback)) { LOG_ERROR("Remote HCI channel SetUp failed."); 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) { LOG_ERROR("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); ASSERT_LOG(ret != -1, "Error setting O_NONBLOCK %s", 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); void BluetoothHci::SetUpLinkLayerServer(ConnectCallback connection_callback) { remote_link_layer_transport_.SetUp(link_socket_server_, connection_callback); test_channel_.RegisterSendResponse([](const std::string& response) { LOG_INFO("No LinkLayer Response channel: %s", response.c_str()); }); if (socket_fd == -1) { LOG_ERROR("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) { LOG_ERROR("Error watching remote LinkLayer channel fd."); return; std::shared_ptr<AsyncDataChannel> BluetoothHci::ConnectToRemoteServer( const std::string& server, int port) { return connector_->ConnectToRemoteServer(server, port); } int flags = fcntl(conn_fd, F_GETFL, NULL); int ret = fcntl(conn_fd, F_SETFL, flags | O_NONBLOCK); ASSERT_LOG(ret != -1, "Error setting O_NONBLOCK %s", strerror(errno)); connection_callback(conn_fd); void BluetoothHci::SetUpTestChannel() { bool transport_configured = test_channel_transport_.SetUp( test_socket_server_, [this](std::shared_ptr<AsyncDataChannel> conn_fd, AsyncDataChannelServer*) { LOG_INFO("Test channel connection accepted."); test_channel_.RegisterSendResponse( [this, conn_fd](const std::string& response) { test_channel_transport_.SendResponse(conn_fd, response); }); } int BluetoothHci::ConnectToRemoteServer(const std::string& server, int port) { int socket_fd = socket(AF_INET, SOCK_STREAM, 0); if (socket_fd < 1) { LOG_INFO("socket() call failed: %s", strerror(errno)); return -1; } struct hostent* host; host = gethostbyname(server.c_str()); if (host == NULL) { LOG_INFO("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) { LOG_INFO("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); ASSERT_LOG(ret != -1, "Error setting O_NONBLOCK %s", strerror(errno)); return socket_fd; } void BluetoothHci::SetUpTestChannel(int port) { int socket_fd = test_channel_transport_.SetUp(port); conn_fd->WatchForNonBlockingRead([this](AsyncDataChannel* conn_fd) { test_channel_transport_.OnCommandReady(conn_fd, []() {}); }); return false; }); test_channel_.RegisterSendResponse([](const std::string& response) { LOG_INFO("No test channel: %s", response.c_str()); }); if (socket_fd == -1) { LOG_ERROR("Test channel SetUp(%d) failed.", port); if (!transport_configured) { LOG_ERROR("Test channel SetUp failed."); return; } LOG_INFO("Test channel SetUp() successful"); async_manager_.WatchFdForNonBlockingReads(socket_fd, [this](int socket_fd) { int conn_fd = test_channel_transport_.Accept(socket_fd); if (conn_fd < 0) { LOG_ERROR("Error watching test channel fd."); return; } LOG_INFO("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); }); }); }); } /* Fallback to shared library if there is no service. */ Loading system/test/rootcanal/bluetooth_hci.h +25 −14 Original line number Diff line number Diff line Loading @@ -16,19 +16,18 @@ #pragma once #include "os/log.h" #include <android/hardware/bluetooth/1.1/IBluetoothHci.h> #include <hidl/MQDescriptor.h> #include "hci_packetizer.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" #include "net/posix/posix_async_socket_connector.h" #include "net/posix/posix_async_socket_server.h" #include "os/log.h" namespace android { namespace hardware { Loading @@ -38,6 +37,11 @@ namespace sim { class BluetoothDeathRecipient; using android::net::AsyncDataChannel; using android::net::AsyncDataChannelConnector; using android::net::AsyncDataChannelServer; using android::net::ConnectCallback; class BluetoothHci : public IBluetoothHci { public: BluetoothHci(); Loading @@ -47,11 +51,14 @@ class BluetoothHci : public IBluetoothHci { ::android::hardware::Return<void> initialize_1_1( const sp<V1_1::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> sendIsoData( const ::android::hardware::hidl_vec<uint8_t>& packet) override; Loading @@ -73,12 +80,17 @@ class BluetoothHci : public IBluetoothHci { void HandleIncomingPacket(); std::shared_ptr<AsyncDataChannelServer> test_socket_server_; std::shared_ptr<AsyncDataChannelServer> hci_socket_server_; std::shared_ptr<AsyncDataChannelServer> link_socket_server_; std::shared_ptr<AsyncDataChannelConnector> connector_; 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); void SetUpTestChannel(); void SetUpHciServer(ConnectCallback on_connect); void SetUpLinkLayerServer(ConnectCallback on_connect); std::shared_ptr<AsyncDataChannel> ConnectToRemoteServer( const std::string& server, int port); std::shared_ptr<test_vendor_lib::DualModeController> controller_; Loading @@ -102,8 +114,8 @@ class BluetoothHci : public IBluetoothHci { task); }, [this](test_vendor_lib::AsyncUserId user_id) { async_manager_.CancelAsyncTasksFromUser(user_id); [this](test_vendor_lib::AsyncUserId user) { async_manager_.CancelAsyncTasksFromUser(user); }, [this](test_vendor_lib::AsyncTaskId task) { Loading @@ -113,7 +125,6 @@ class BluetoothHci : public IBluetoothHci { [this](const std::string& server, int port) { return ConnectToRemoteServer(server, port); }}; test_vendor_lib::TestCommandHandler test_channel_{test_model_}; }; Loading system/vendor_libs/test_vendor_lib/Android.bp +0 −1 Original line number Diff line number Diff line Loading @@ -39,7 +39,6 @@ cc_library_static { "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/scripted_beacon.cc", "model/devices/sniffer.cc", Loading system/vendor_libs/test_vendor_lib/desktop/root_canal_main.cc +16 −10 Original line number Diff line number Diff line Loading @@ -13,21 +13,24 @@ // See the License for the specific language governing permissions and // limitations under the License. // #include "test_environment.h" #include <future> #include <client/linux/handler/exception_handler.h> #include <backtrace/Backtrace.h> #include <backtrace/backtrace_constants.h> #include <client/linux/handler/exception_handler.h> #include <gflags/gflags.h> #include <future> #include "model/setup/async_manager.h" #include "net/posix/posix_async_socket_connector.h" #include "net/posix/posix_async_socket_server.h" #include "os/log.h" using ::android::bluetooth::root_canal::TestEnvironment; using ::android::net::PosixAsyncSocketConnector; using ::android::net::PosixAsyncSocketServer; using test_vendor_lib::AsyncManager; DEFINE_string(controller_properties_file, "", "controller_properties.json file path"); Loading Loading @@ -111,10 +114,13 @@ int main(int argc, char** argv) { } } } TestEnvironment root_canal(test_port, hci_server_port, link_server_port, FLAGS_controller_properties_file, FLAGS_default_commands_file); AsyncManager am; TestEnvironment root_canal( std::make_shared<PosixAsyncSocketServer>(test_port, &am), std::make_shared<PosixAsyncSocketServer>(hci_server_port, &am), std::make_shared<PosixAsyncSocketServer>(link_server_port, &am), std::make_shared<PosixAsyncSocketConnector>(&am), FLAGS_controller_properties_file, FLAGS_default_commands_file); std::promise<void> barrier; std::future<void> barrier_future = barrier.get_future(); root_canal.initialize(std::move(barrier)); Loading system/vendor_libs/test_vendor_lib/desktop/test_environment.cc +53 −117 Original line number Diff line number Diff line Loading @@ -16,14 +16,12 @@ #include "test_environment.h" #include <fcntl.h> #include <netdb.h> #include <netinet/in.h> #include <signal.h> #include <string.h> #include <unistd.h> #include <type_traits> // for remove_extent_t #include <utility> // for move #include <vector> // for vector #include "os/log.h" #include "net/async_data_channel.h" // for AsyncDataChannel #include "os/log.h" // for LOG_INFO, LOG_ERROR, LOG_WARN namespace android { namespace bluetooth { Loading Loading @@ -52,13 +50,16 @@ void TestEnvironment::initialize(std::promise<void> barrier) { }); SetUpTestChannel(); SetUpHciServer([this](int fd) { test_model_.IncomingHciConnection(fd); }); SetUpLinkLayerServer([this](int fd) { test_model_.IncomingLinkLayerConnection(fd); }); // In case the client socket is closed, and rootcanal doesn't detect it due to // TimerTick not fired, writing to the socket causes a SIGPIPE and we need to // catch it to prevent rootcanal from crash signal(SIGPIPE, SIG_IGN); SetUpHciServer([this](std::shared_ptr<AsyncDataChannel> socket, AsyncDataChannelServer* srv) { test_model_.IncomingHciConnection(socket); srv->StartListening(); }); SetUpLinkLayerServer([this](std::shared_ptr<AsyncDataChannel> socket, AsyncDataChannelServer* srv) { test_model_.IncomingLinkLayerConnection(socket); srv->StartListening(); }); LOG_INFO("%s: Finished", __func__); } Loading @@ -68,92 +69,54 @@ void TestEnvironment::close() { test_model_.Reset(); } void TestEnvironment::SetUpHciServer(const std::function<void(int)>& connection_callback) { int socket_fd = remote_hci_transport_.SetUp(hci_server_port_); test_channel_.RegisterSendResponse( [](const std::string& response) { LOG_INFO("No HCI Response channel: %s", response.c_str()); }); if (socket_fd == -1) { LOG_ERROR("Remote HCI channel SetUp(%d) failed.", hci_server_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) { LOG_ERROR("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); ASSERT_LOG(ret != -1, "Error setting O_NONBLOCK %s", strerror(errno)); connection_callback(conn_fd); void TestEnvironment::SetUpHciServer(ConnectCallback connection_callback) { test_channel_.RegisterSendResponse([](const std::string& response) { LOG_INFO("No HCI Response channel: %s", response.c_str()); }); } void TestEnvironment::SetUpLinkLayerServer(const std::function<void(int)>& connection_callback) { int socket_fd = remote_link_layer_transport_.SetUp(link_server_port_); test_channel_.RegisterSendResponse( [](const std::string& response) { LOG_INFO("No LinkLayer Response channel: %s", response.c_str()); }); if (socket_fd == -1) { LOG_ERROR("Remote LinkLayer channel SetUp(%d) failed.", link_server_port_); if (!remote_hci_transport_.SetUp(hci_socket_server_, connection_callback)) { LOG_ERROR("Remote HCI channel SetUp failed."); 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) { LOG_ERROR("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); ASSERT_LOG(ret != -1, "Error setting O_NONBLOCK %s", strerror(errno)); connection_callback(conn_fd); }); } int TestEnvironment::ConnectToRemoteServer(const std::string& server, int port) { int socket_fd = socket(AF_INET, SOCK_STREAM, 0); if (socket_fd < 1) { LOG_INFO("socket() call failed: %s", strerror(errno)); return -1; } void TestEnvironment::SetUpLinkLayerServer( ConnectCallback connection_callback) { remote_link_layer_transport_.SetUp(link_socket_server_, connection_callback); struct hostent* host; host = gethostbyname(server.c_str()); if (host == NULL) { LOG_INFO("gethostbyname() failed for %s: %s", server.c_str(), strerror(errno)); return -1; test_channel_.RegisterSendResponse([](const std::string& response) { LOG_INFO("No LinkLayer Response channel: %s", response.c_str()); }); } 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) { LOG_INFO("connect() failed for %s@%d: %s", server.c_str(), port, strerror(errno)); return -1; std::shared_ptr<AsyncDataChannel> TestEnvironment::ConnectToRemoteServer( const std::string& server, int port) { return connector_->ConnectToRemoteServer(server, port); } int flags = fcntl(socket_fd, F_GETFL, NULL); int ret = fcntl(socket_fd, F_SETFL, flags | O_NONBLOCK); ASSERT_LOG(ret != -1, "Error setting O_NONBLOCK %s", strerror(errno)); return socket_fd; void TestEnvironment::SetUpTestChannel() { bool transport_configured = test_channel_transport_.SetUp( test_socket_server_, [this](std::shared_ptr<AsyncDataChannel> conn_fd, AsyncDataChannelServer*) { LOG_INFO("Test channel connection accepted."); if (test_channel_open_) { LOG_WARN("Only one connection at a time is supported"); test_channel_transport_.SendResponse(conn_fd, "The connection is broken"); return false; } test_channel_open_ = true; test_channel_.RegisterSendResponse( [this, conn_fd](const std::string& response) { test_channel_transport_.SendResponse(conn_fd, response); }); void TestEnvironment::SetUpTestChannel() { int socket_fd = test_channel_transport_.SetUp(test_port_); conn_fd->WatchForNonBlockingRead([this](AsyncDataChannel* conn_fd) { test_channel_transport_.OnCommandReady( conn_fd, [this]() { test_channel_open_ = false; }); }); return false; }); test_channel_.RegisterSendResponse([](const std::string& response) { LOG_INFO("No test channel: %s", response.c_str()); }); Loading @@ -164,39 +127,12 @@ void TestEnvironment::SetUpTestChannel() { test_channel_.FromFile(default_commands_file_); if (socket_fd == -1) { LOG_ERROR("Test channel SetUp(%d) failed.", test_port_); if (!transport_configured) { LOG_ERROR("Test channel SetUp failed."); return; } LOG_INFO("Test channel SetUp() successful"); async_manager_.WatchFdForNonBlockingReads(socket_fd, [this](int socket_fd) { int conn_fd = test_channel_transport_.Accept(socket_fd); if (conn_fd < 0) { LOG_ERROR("Error watching test channel fd."); barrier_.set_value(); return; } LOG_INFO("Test channel connection accepted."); if (test_channel_open_) { LOG_WARN("Only one connection at a time is supported"); async_manager_.StopWatchingFileDescriptor(conn_fd); test_channel_transport_.SendResponse(conn_fd, "The connection is broken"); return; } test_channel_open_ = true; 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_open_ = false; }); }); }); } } // namespace root_canal Loading Loading
system/test/rootcanal/bluetooth_hci.cc +51 −106 Original line number Diff line number Diff line Loading @@ -18,13 +18,13 @@ #include "bluetooth_hci.h" #include "log/log.h" #include <cutils/properties.h> #include <netdb.h> #include <netinet/in.h> #include <string.h> #include "hci_internals.h" #include "log/log.h" namespace android { namespace hardware { Loading Loading @@ -58,18 +58,15 @@ class BluetoothDeathRecipient : public hidl_death_recipient { 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<V1_0::IBluetoothHciCallbacks>& cb) { Loading Loading @@ -104,7 +101,8 @@ Return<void> BluetoothHci::initialize_impl( controller_ = std::make_shared<DualModeController>(); char mac_property[PROPERTY_VALUE_MAX] = ""; property_get("vendor.bt.rootcanal_mac_address", mac_property, "3C:5A:B4:01:02:03"); property_get("vendor.bt.rootcanal_mac_address", mac_property, "3C:5A:B4:01:02:03"); controller_->Initialize({"dmc", std::string(mac_property)}); controller_->RegisterEventChannel( Loading Loading @@ -193,11 +191,25 @@ Return<void> BluetoothHci::initialize_impl( }); if (BtTestConsoleEnabled()) { SetUpTestChannel(6111); SetUpHciServer(6211, [this](int fd) { test_model_.IncomingHciConnection(fd); }); SetUpLinkLayerServer( 6311, [this](int fd) { test_model_.IncomingLinkLayerConnection(fd); }); test_socket_server_ = std::make_shared<net::PosixAsyncSocketServer>(6111, &async_manager_); hci_socket_server_ = std::make_shared<net::PosixAsyncSocketServer>(6211, &async_manager_); link_socket_server_ = std::make_shared<net::PosixAsyncSocketServer>(6311, &async_manager_); connector_ = std::make_shared<net::PosixAsyncSocketConnector>(&async_manager_); SetUpTestChannel(); SetUpHciServer([this](std::shared_ptr<AsyncDataChannel> socket, AsyncDataChannelServer* srv) { test_model_.IncomingHciConnection(socket); srv->StartListening(); }); SetUpLinkLayerServer([this](std::shared_ptr<AsyncDataChannel> socket, AsyncDataChannelServer* srv) { test_model_.IncomingLinkLayerConnection(socket); srv->StartListening(); }); } else { // This should be configurable in the future. LOG_INFO("Adding Beacons so the scan list is not empty."); Loading Loading @@ -283,122 +295,55 @@ Return<void> BluetoothHci::sendIsoData(const hidl_vec<uint8_t>& packet) { return Void(); } void BluetoothHci::SetUpHciServer(int port, const std::function<void(int)>& connection_callback) { int socket_fd = remote_hci_transport_.SetUp(port); void BluetoothHci::SetUpHciServer(ConnectCallback connection_callback) { test_channel_.RegisterSendResponse([](const std::string& response) { LOG_INFO("No HCI Response channel: %s", response.c_str()); }); if (socket_fd == -1) { LOG_ERROR("Remote HCI channel SetUp(%d) failed.", port); if (!remote_hci_transport_.SetUp(hci_socket_server_, connection_callback)) { LOG_ERROR("Remote HCI channel SetUp failed."); 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) { LOG_ERROR("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); ASSERT_LOG(ret != -1, "Error setting O_NONBLOCK %s", 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); void BluetoothHci::SetUpLinkLayerServer(ConnectCallback connection_callback) { remote_link_layer_transport_.SetUp(link_socket_server_, connection_callback); test_channel_.RegisterSendResponse([](const std::string& response) { LOG_INFO("No LinkLayer Response channel: %s", response.c_str()); }); if (socket_fd == -1) { LOG_ERROR("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) { LOG_ERROR("Error watching remote LinkLayer channel fd."); return; std::shared_ptr<AsyncDataChannel> BluetoothHci::ConnectToRemoteServer( const std::string& server, int port) { return connector_->ConnectToRemoteServer(server, port); } int flags = fcntl(conn_fd, F_GETFL, NULL); int ret = fcntl(conn_fd, F_SETFL, flags | O_NONBLOCK); ASSERT_LOG(ret != -1, "Error setting O_NONBLOCK %s", strerror(errno)); connection_callback(conn_fd); void BluetoothHci::SetUpTestChannel() { bool transport_configured = test_channel_transport_.SetUp( test_socket_server_, [this](std::shared_ptr<AsyncDataChannel> conn_fd, AsyncDataChannelServer*) { LOG_INFO("Test channel connection accepted."); test_channel_.RegisterSendResponse( [this, conn_fd](const std::string& response) { test_channel_transport_.SendResponse(conn_fd, response); }); } int BluetoothHci::ConnectToRemoteServer(const std::string& server, int port) { int socket_fd = socket(AF_INET, SOCK_STREAM, 0); if (socket_fd < 1) { LOG_INFO("socket() call failed: %s", strerror(errno)); return -1; } struct hostent* host; host = gethostbyname(server.c_str()); if (host == NULL) { LOG_INFO("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) { LOG_INFO("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); ASSERT_LOG(ret != -1, "Error setting O_NONBLOCK %s", strerror(errno)); return socket_fd; } void BluetoothHci::SetUpTestChannel(int port) { int socket_fd = test_channel_transport_.SetUp(port); conn_fd->WatchForNonBlockingRead([this](AsyncDataChannel* conn_fd) { test_channel_transport_.OnCommandReady(conn_fd, []() {}); }); return false; }); test_channel_.RegisterSendResponse([](const std::string& response) { LOG_INFO("No test channel: %s", response.c_str()); }); if (socket_fd == -1) { LOG_ERROR("Test channel SetUp(%d) failed.", port); if (!transport_configured) { LOG_ERROR("Test channel SetUp failed."); return; } LOG_INFO("Test channel SetUp() successful"); async_manager_.WatchFdForNonBlockingReads(socket_fd, [this](int socket_fd) { int conn_fd = test_channel_transport_.Accept(socket_fd); if (conn_fd < 0) { LOG_ERROR("Error watching test channel fd."); return; } LOG_INFO("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); }); }); }); } /* Fallback to shared library if there is no service. */ Loading
system/test/rootcanal/bluetooth_hci.h +25 −14 Original line number Diff line number Diff line Loading @@ -16,19 +16,18 @@ #pragma once #include "os/log.h" #include <android/hardware/bluetooth/1.1/IBluetoothHci.h> #include <hidl/MQDescriptor.h> #include "hci_packetizer.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" #include "net/posix/posix_async_socket_connector.h" #include "net/posix/posix_async_socket_server.h" #include "os/log.h" namespace android { namespace hardware { Loading @@ -38,6 +37,11 @@ namespace sim { class BluetoothDeathRecipient; using android::net::AsyncDataChannel; using android::net::AsyncDataChannelConnector; using android::net::AsyncDataChannelServer; using android::net::ConnectCallback; class BluetoothHci : public IBluetoothHci { public: BluetoothHci(); Loading @@ -47,11 +51,14 @@ class BluetoothHci : public IBluetoothHci { ::android::hardware::Return<void> initialize_1_1( const sp<V1_1::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> sendIsoData( const ::android::hardware::hidl_vec<uint8_t>& packet) override; Loading @@ -73,12 +80,17 @@ class BluetoothHci : public IBluetoothHci { void HandleIncomingPacket(); std::shared_ptr<AsyncDataChannelServer> test_socket_server_; std::shared_ptr<AsyncDataChannelServer> hci_socket_server_; std::shared_ptr<AsyncDataChannelServer> link_socket_server_; std::shared_ptr<AsyncDataChannelConnector> connector_; 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); void SetUpTestChannel(); void SetUpHciServer(ConnectCallback on_connect); void SetUpLinkLayerServer(ConnectCallback on_connect); std::shared_ptr<AsyncDataChannel> ConnectToRemoteServer( const std::string& server, int port); std::shared_ptr<test_vendor_lib::DualModeController> controller_; Loading @@ -102,8 +114,8 @@ class BluetoothHci : public IBluetoothHci { task); }, [this](test_vendor_lib::AsyncUserId user_id) { async_manager_.CancelAsyncTasksFromUser(user_id); [this](test_vendor_lib::AsyncUserId user) { async_manager_.CancelAsyncTasksFromUser(user); }, [this](test_vendor_lib::AsyncTaskId task) { Loading @@ -113,7 +125,6 @@ class BluetoothHci : public IBluetoothHci { [this](const std::string& server, int port) { return ConnectToRemoteServer(server, port); }}; test_vendor_lib::TestCommandHandler test_channel_{test_model_}; }; Loading
system/vendor_libs/test_vendor_lib/Android.bp +0 −1 Original line number Diff line number Diff line Loading @@ -39,7 +39,6 @@ cc_library_static { "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/scripted_beacon.cc", "model/devices/sniffer.cc", Loading
system/vendor_libs/test_vendor_lib/desktop/root_canal_main.cc +16 −10 Original line number Diff line number Diff line Loading @@ -13,21 +13,24 @@ // See the License for the specific language governing permissions and // limitations under the License. // #include "test_environment.h" #include <future> #include <client/linux/handler/exception_handler.h> #include <backtrace/Backtrace.h> #include <backtrace/backtrace_constants.h> #include <client/linux/handler/exception_handler.h> #include <gflags/gflags.h> #include <future> #include "model/setup/async_manager.h" #include "net/posix/posix_async_socket_connector.h" #include "net/posix/posix_async_socket_server.h" #include "os/log.h" using ::android::bluetooth::root_canal::TestEnvironment; using ::android::net::PosixAsyncSocketConnector; using ::android::net::PosixAsyncSocketServer; using test_vendor_lib::AsyncManager; DEFINE_string(controller_properties_file, "", "controller_properties.json file path"); Loading Loading @@ -111,10 +114,13 @@ int main(int argc, char** argv) { } } } TestEnvironment root_canal(test_port, hci_server_port, link_server_port, FLAGS_controller_properties_file, FLAGS_default_commands_file); AsyncManager am; TestEnvironment root_canal( std::make_shared<PosixAsyncSocketServer>(test_port, &am), std::make_shared<PosixAsyncSocketServer>(hci_server_port, &am), std::make_shared<PosixAsyncSocketServer>(link_server_port, &am), std::make_shared<PosixAsyncSocketConnector>(&am), FLAGS_controller_properties_file, FLAGS_default_commands_file); std::promise<void> barrier; std::future<void> barrier_future = barrier.get_future(); root_canal.initialize(std::move(barrier)); Loading
system/vendor_libs/test_vendor_lib/desktop/test_environment.cc +53 −117 Original line number Diff line number Diff line Loading @@ -16,14 +16,12 @@ #include "test_environment.h" #include <fcntl.h> #include <netdb.h> #include <netinet/in.h> #include <signal.h> #include <string.h> #include <unistd.h> #include <type_traits> // for remove_extent_t #include <utility> // for move #include <vector> // for vector #include "os/log.h" #include "net/async_data_channel.h" // for AsyncDataChannel #include "os/log.h" // for LOG_INFO, LOG_ERROR, LOG_WARN namespace android { namespace bluetooth { Loading Loading @@ -52,13 +50,16 @@ void TestEnvironment::initialize(std::promise<void> barrier) { }); SetUpTestChannel(); SetUpHciServer([this](int fd) { test_model_.IncomingHciConnection(fd); }); SetUpLinkLayerServer([this](int fd) { test_model_.IncomingLinkLayerConnection(fd); }); // In case the client socket is closed, and rootcanal doesn't detect it due to // TimerTick not fired, writing to the socket causes a SIGPIPE and we need to // catch it to prevent rootcanal from crash signal(SIGPIPE, SIG_IGN); SetUpHciServer([this](std::shared_ptr<AsyncDataChannel> socket, AsyncDataChannelServer* srv) { test_model_.IncomingHciConnection(socket); srv->StartListening(); }); SetUpLinkLayerServer([this](std::shared_ptr<AsyncDataChannel> socket, AsyncDataChannelServer* srv) { test_model_.IncomingLinkLayerConnection(socket); srv->StartListening(); }); LOG_INFO("%s: Finished", __func__); } Loading @@ -68,92 +69,54 @@ void TestEnvironment::close() { test_model_.Reset(); } void TestEnvironment::SetUpHciServer(const std::function<void(int)>& connection_callback) { int socket_fd = remote_hci_transport_.SetUp(hci_server_port_); test_channel_.RegisterSendResponse( [](const std::string& response) { LOG_INFO("No HCI Response channel: %s", response.c_str()); }); if (socket_fd == -1) { LOG_ERROR("Remote HCI channel SetUp(%d) failed.", hci_server_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) { LOG_ERROR("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); ASSERT_LOG(ret != -1, "Error setting O_NONBLOCK %s", strerror(errno)); connection_callback(conn_fd); void TestEnvironment::SetUpHciServer(ConnectCallback connection_callback) { test_channel_.RegisterSendResponse([](const std::string& response) { LOG_INFO("No HCI Response channel: %s", response.c_str()); }); } void TestEnvironment::SetUpLinkLayerServer(const std::function<void(int)>& connection_callback) { int socket_fd = remote_link_layer_transport_.SetUp(link_server_port_); test_channel_.RegisterSendResponse( [](const std::string& response) { LOG_INFO("No LinkLayer Response channel: %s", response.c_str()); }); if (socket_fd == -1) { LOG_ERROR("Remote LinkLayer channel SetUp(%d) failed.", link_server_port_); if (!remote_hci_transport_.SetUp(hci_socket_server_, connection_callback)) { LOG_ERROR("Remote HCI channel SetUp failed."); 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) { LOG_ERROR("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); ASSERT_LOG(ret != -1, "Error setting O_NONBLOCK %s", strerror(errno)); connection_callback(conn_fd); }); } int TestEnvironment::ConnectToRemoteServer(const std::string& server, int port) { int socket_fd = socket(AF_INET, SOCK_STREAM, 0); if (socket_fd < 1) { LOG_INFO("socket() call failed: %s", strerror(errno)); return -1; } void TestEnvironment::SetUpLinkLayerServer( ConnectCallback connection_callback) { remote_link_layer_transport_.SetUp(link_socket_server_, connection_callback); struct hostent* host; host = gethostbyname(server.c_str()); if (host == NULL) { LOG_INFO("gethostbyname() failed for %s: %s", server.c_str(), strerror(errno)); return -1; test_channel_.RegisterSendResponse([](const std::string& response) { LOG_INFO("No LinkLayer Response channel: %s", response.c_str()); }); } 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) { LOG_INFO("connect() failed for %s@%d: %s", server.c_str(), port, strerror(errno)); return -1; std::shared_ptr<AsyncDataChannel> TestEnvironment::ConnectToRemoteServer( const std::string& server, int port) { return connector_->ConnectToRemoteServer(server, port); } int flags = fcntl(socket_fd, F_GETFL, NULL); int ret = fcntl(socket_fd, F_SETFL, flags | O_NONBLOCK); ASSERT_LOG(ret != -1, "Error setting O_NONBLOCK %s", strerror(errno)); return socket_fd; void TestEnvironment::SetUpTestChannel() { bool transport_configured = test_channel_transport_.SetUp( test_socket_server_, [this](std::shared_ptr<AsyncDataChannel> conn_fd, AsyncDataChannelServer*) { LOG_INFO("Test channel connection accepted."); if (test_channel_open_) { LOG_WARN("Only one connection at a time is supported"); test_channel_transport_.SendResponse(conn_fd, "The connection is broken"); return false; } test_channel_open_ = true; test_channel_.RegisterSendResponse( [this, conn_fd](const std::string& response) { test_channel_transport_.SendResponse(conn_fd, response); }); void TestEnvironment::SetUpTestChannel() { int socket_fd = test_channel_transport_.SetUp(test_port_); conn_fd->WatchForNonBlockingRead([this](AsyncDataChannel* conn_fd) { test_channel_transport_.OnCommandReady( conn_fd, [this]() { test_channel_open_ = false; }); }); return false; }); test_channel_.RegisterSendResponse([](const std::string& response) { LOG_INFO("No test channel: %s", response.c_str()); }); Loading @@ -164,39 +127,12 @@ void TestEnvironment::SetUpTestChannel() { test_channel_.FromFile(default_commands_file_); if (socket_fd == -1) { LOG_ERROR("Test channel SetUp(%d) failed.", test_port_); if (!transport_configured) { LOG_ERROR("Test channel SetUp failed."); return; } LOG_INFO("Test channel SetUp() successful"); async_manager_.WatchFdForNonBlockingReads(socket_fd, [this](int socket_fd) { int conn_fd = test_channel_transport_.Accept(socket_fd); if (conn_fd < 0) { LOG_ERROR("Error watching test channel fd."); barrier_.set_value(); return; } LOG_INFO("Test channel connection accepted."); if (test_channel_open_) { LOG_WARN("Only one connection at a time is supported"); async_manager_.StopWatchingFileDescriptor(conn_fd); test_channel_transport_.SendResponse(conn_fd, "The connection is broken"); return; } test_channel_open_ = true; 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_open_ = false; }); }); }); } } // namespace root_canal Loading