Loading system/gd/Android.bp +2 −2 Original line number Diff line number Diff line Loading @@ -126,7 +126,7 @@ cc_defaults { host: { srcs: [ ":BluetoothBtaaSources_host", ":BluetoothHalSources_hci_rootcanal", ":BluetoothHalSources_hci_host", ":BluetoothOsSources_host", ], }, Loading Loading @@ -295,7 +295,7 @@ cc_test { }, host: { srcs: [ ":BluetoothHalTestSources_hci_rootcanal", ":BluetoothHalTestSources_hci_host", ":BluetoothOsTestSources_host", ], }, Loading system/gd/docs/architecture/style_guide.md +4 −4 Original line number Diff line number Diff line Loading @@ -113,10 +113,10 @@ Root directory under Android tree: * hci_hal_android_hidl.cc: implementation of hci_hal.h using Android HIDL * hci_hal_android_hidl_test.cc: unit tests for the Android HIDL implementation * hci_hal_host_rootcanal.cc: implementation of hci_hal.h using root-canal emulator * hci_hal_host_rootcanal_test.cc: unit tests for the root-canal emulator implementation * hci_hal_host.cc: implementation of hci_hal.h using root-canal emulator or linux Bluetooth HCI socket * hci_hal_host_test.cc: unit tests for the socket based HAL (root-canal) emulator implementation * facade.proto: gRPC automation interface definition for this layer * facade.h/cc: an implementation of the above gRPC interface for the GD stack Loading system/gd/facade/facade_main.cc +1 −1 Original line number Diff line number Diff line Loading @@ -35,7 +35,7 @@ #include "common/init_flags.h" #include "facade/grpc_root_server.h" #include "hal/hci_hal_host_rootcanal.h" #include "hal/hci_hal_host.h" #include "hal/snoop_logger.h" #include "os/log.h" #include "os/parameter_provider.h" Loading system/gd/hal/Android.bp +4 −4 Original line number Diff line number Diff line Loading @@ -22,9 +22,9 @@ filegroup { } filegroup { name: "BluetoothHalSources_hci_rootcanal", name: "BluetoothHalSources_hci_host", srcs: [ "hci_hal_host_rootcanal.cc", "hci_hal_host.cc", ], } Loading @@ -36,9 +36,9 @@ filegroup { } filegroup { name: "BluetoothHalTestSources_hci_rootcanal", name: "BluetoothHalTestSources_hci_host", srcs: [ "hci_hal_host_rootcanal_test.cc", "hci_hal_host_test.cc", ], } Loading system/gd/hal/hci_hal_host_rootcanal.cc→system/gd/hal/hci_hal_host.cc +174 −22 Original line number Diff line number Diff line Loading @@ -14,9 +14,10 @@ * limitations under the License. */ #include "hal/hci_hal_host_rootcanal.h" #include "hal/hci_hal_host.h" #include <netdb.h> #include <poll.h> #include <sys/socket.h> #include <sys/types.h> #include <unistd.h> Loading Loading @@ -48,7 +49,160 @@ constexpr uint8_t kHciEvtHeaderSize = 2; constexpr uint8_t kHciIsoHeaderSize = 4; constexpr int kBufSize = 1024 + 4 + 1; // DeviceProperties::acl_data_packet_size_ + ACL header + H4 header int ConnectToRootCanal(const std::string& server, int port) { #ifdef USE_LINUX_HCI_SOCKET constexpr uint8_t BTPROTO_HCI = 1; constexpr uint16_t HCI_CHANNEL_USER = 1; constexpr uint16_t HCI_CHANNEL_CONTROL = 3; constexpr uint16_t HCI_DEV_NONE = 0xffff; /* reference from <kernel>/include/net/bluetooth/mgmt.h */ #define MGMT_OP_INDEX_LIST 0x0003 #define MGMT_EV_INDEX_ADDED 0x0004 #define MGMT_EV_COMMAND_COMP 0x0001 #define MGMT_EV_SIZE_MAX 1024 #define WRITE_NO_INTR(fn) \ do { \ } while ((fn) == -1 && errno == EINTR) struct sockaddr_hci { sa_family_t hci_family; unsigned short hci_dev; unsigned short hci_channel; }; struct mgmt_pkt { uint16_t opcode; uint16_t index; uint16_t len; uint8_t data[MGMT_EV_SIZE_MAX]; } __attribute__((packed)); struct mgmt_event_read_index { uint16_t cc_opcode; uint8_t status; uint16_t num_intf; uint16_t index[0]; } __attribute__((packed)); int waitHciDev(int hci_interface) { struct sockaddr_hci addr; struct pollfd fds[1]; struct mgmt_pkt ev; int fd; int ret = 0; fd = socket(PF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); if (fd < 0) { LOG_ERROR("Bluetooth socket error: %s", strerror(errno)); return -1; } memset(&addr, 0, sizeof(addr)); addr.hci_family = AF_BLUETOOTH; addr.hci_dev = HCI_DEV_NONE; addr.hci_channel = HCI_CHANNEL_CONTROL; if (bind(fd, (struct sockaddr*)&addr, sizeof(addr)) < 0) { LOG_ERROR("HCI Channel Control: %s", strerror(errno)); close(fd); return -1; } fds[0].fd = fd; fds[0].events = POLLIN; /* Read Controller Index List Command */ ev.opcode = MGMT_OP_INDEX_LIST; ev.index = HCI_DEV_NONE; ev.len = 0; ssize_t wrote; WRITE_NO_INTR(wrote = write(fd, &ev, 6)); if (wrote != 6) { LOG_ERROR("Unable to write mgmt command: %s", strerror(errno)); close(fd); return -1; } /* validate mentioned hci interface is present and registered with sock system */ while (1) { int n; WRITE_NO_INTR(n = poll(fds, 1, -1)); if (n == -1) { LOG_ERROR("Poll error: %s", strerror(errno)); ret = -1; break; } else if (n == 0) { LOG_ERROR("Timeout, no HCI device detected"); ret = -1; break; } if (fds[0].revents & POLLIN) { WRITE_NO_INTR(n = read(fd, &ev, sizeof(struct mgmt_pkt))); if (n < 0) { LOG_ERROR("Error reading control channel: %s", strerror(errno)); ret = -1; break; } if (ev.opcode == MGMT_EV_INDEX_ADDED && ev.index == hci_interface) { close(fd); return -1; } else if (ev.opcode == MGMT_EV_COMMAND_COMP) { struct mgmt_event_read_index* cc; int i; cc = (struct mgmt_event_read_index*)ev.data; if (cc->cc_opcode != MGMT_OP_INDEX_LIST || cc->status != 0) continue; for (i = 0; i < cc->num_intf; i++) { if (cc->index[i] == hci_interface) { close(fd); return 0; } } } } } close(fd); return -1; } // Connect to Linux HCI socket int ConnectToSocket() { int socket_fd = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); if (socket_fd < 1) { LOG_ERROR("can't create socket: %s", strerror(errno)); return INVALID_FD; } int hci_interface = 0; // Assume we only have HCI 0 if (waitHciDev(hci_interface) != 0) { ::close(socket_fd); return INVALID_FD; } struct sockaddr_hci addr; memset(&addr, 0, sizeof(addr)); addr.hci_family = AF_BLUETOOTH; addr.hci_dev = hci_interface; addr.hci_channel = HCI_CHANNEL_USER; if (bind(socket_fd, (struct sockaddr*)&addr, sizeof(addr)) < 0) { LOG_ERROR("HCI Channel Control: %s", strerror(errno)); ::close(socket_fd); return INVALID_FD; } LOG_INFO("HCI device ready"); return socket_fd; } #else // Connect to root canal socket int ConnectToSocket() { auto* config = bluetooth::hal::HciHalHostRootcanalConfig::Get(); const std::string& server = config->GetServerAddress(); int port = config->GetPort(); int socket_fd = socket(AF_INET, SOCK_STREAM, 0); if (socket_fd < 1) { LOG_ERROR("can't create socket: %s", strerror(errno)); Loading Loading @@ -85,12 +239,13 @@ int ConnectToRootCanal(const std::string& server, int port) { } return socket_fd; } #endif } // namespace namespace bluetooth { namespace hal { class HciHalHostRootcanal : public HciHal { class HciHalHost : public HciHal { public: void registerIncomingPacketCallback(HciHalCallbacks* callback) override { std::lock_guard<std::mutex> lock(api_mutex_); Loading Loading @@ -119,7 +274,7 @@ class HciHalHostRootcanal : public HciHal { std::vector<uint8_t> packet = std::move(command); btsnoop_logger_->Capture(packet, SnoopLogger::Direction::OUTGOING, SnoopLogger::PacketType::CMD); packet.insert(packet.cbegin(), kH4Command); write_to_rootcanal_fd(packet); write_to_fd(packet); } void sendAclData(HciPacket data) override { Loading @@ -128,7 +283,7 @@ class HciHalHostRootcanal : public HciHal { std::vector<uint8_t> packet = std::move(data); btsnoop_logger_->Capture(packet, SnoopLogger::Direction::OUTGOING, SnoopLogger::PacketType::ACL); packet.insert(packet.cbegin(), kH4Acl); write_to_rootcanal_fd(packet); write_to_fd(packet); } void sendScoData(HciPacket data) override { Loading @@ -137,7 +292,7 @@ class HciHalHostRootcanal : public HciHal { std::vector<uint8_t> packet = std::move(data); btsnoop_logger_->Capture(packet, SnoopLogger::Direction::OUTGOING, SnoopLogger::PacketType::SCO); packet.insert(packet.cbegin(), kH4Sco); write_to_rootcanal_fd(packet); write_to_fd(packet); } void sendIsoData(HciPacket data) override { Loading @@ -146,7 +301,7 @@ class HciHalHostRootcanal : public HciHal { std::vector<uint8_t> packet = std::move(data); btsnoop_logger_->Capture(packet, SnoopLogger::Direction::OUTGOING, SnoopLogger::PacketType::ISO); packet.insert(packet.cbegin(), kH4Iso); write_to_rootcanal_fd(packet); write_to_fd(packet); } protected: Loading @@ -157,25 +312,23 @@ class HciHalHostRootcanal : public HciHal { void Start() override { std::lock_guard<std::mutex> lock(api_mutex_); ASSERT(sock_fd_ == INVALID_FD); sock_fd_ = ConnectToRootCanal(config_->GetServerAddress(), config_->GetPort()); sock_fd_ = ConnectToSocket(); ASSERT(sock_fd_ != INVALID_FD); reactable_ = hci_incoming_thread_.GetReactor()->Register( sock_fd_, common::Bind(&HciHalHostRootcanal::incoming_packet_received, common::Unretained(this)), common::Closure()); sock_fd_, common::Bind(&HciHalHost::incoming_packet_received, common::Unretained(this)), common::Closure()); btsnoop_logger_ = GetDependency<SnoopLogger>(); LOG_INFO("Rootcanal HAL opened successfully"); LOG_INFO("HAL opened successfully"); } void Stop() override { std::lock_guard<std::mutex> lock(api_mutex_); LOG_INFO("Rootcanal HAL is closing"); LOG_INFO("HAL is closing"); if (reactable_ != nullptr) { hci_incoming_thread_.GetReactor()->Unregister(reactable_); LOG_INFO("Rootcanal HAL is stopping, start waiting for last callback"); LOG_INFO("HAL is stopping, start waiting for last callback"); // Wait up to 1 second for the last incoming packet callback to finish hci_incoming_thread_.GetReactor()->WaitForUnregisteredReactable(std::chrono::milliseconds(1000)); LOG_INFO("Rootcanal HAL is stopping, finished waiting for last callback"); LOG_INFO("HAL is stopping, finished waiting for last callback"); ASSERT(sock_fd_ != INVALID_FD); } reactable_ = nullptr; Loading @@ -185,13 +338,12 @@ class HciHalHostRootcanal : public HciHal { } ::close(sock_fd_); sock_fd_ = INVALID_FD; LOG_INFO("Rootcanal HAL is closed"); LOG_INFO("HAL is closed"); } private: // Held when APIs are called, NOT to be held during callbacks std::mutex api_mutex_; HciHalHostRootcanalConfig* config_ = HciHalHostRootcanalConfig::Get(); HciHalCallbacks* incoming_packet_callback_ = nullptr; std::mutex incoming_packet_callback_mutex_; int sock_fd_ = INVALID_FD; Loading @@ -201,14 +353,14 @@ class HciHalHostRootcanal : public HciHal { std::queue<std::vector<uint8_t>> hci_outgoing_queue_; SnoopLogger* btsnoop_logger_ = nullptr; void write_to_rootcanal_fd(HciPacket packet) { void write_to_fd(HciPacket packet) { // TODO: replace this with new queue when it's ready hci_outgoing_queue_.emplace(packet); if (hci_outgoing_queue_.size() == 1) { hci_incoming_thread_.GetReactor()->ModifyRegistration( reactable_, common::Bind(&HciHalHostRootcanal::incoming_packet_received, common::Unretained(this)), common::Bind(&HciHalHostRootcanal::send_packet_ready, common::Unretained(this))); common::Bind(&HciHalHost::incoming_packet_received, common::Unretained(this)), common::Bind(&HciHalHost::send_packet_ready, common::Unretained(this))); } } Loading @@ -223,7 +375,7 @@ class HciHalHostRootcanal : public HciHal { if (hci_outgoing_queue_.empty()) { this->hci_incoming_thread_.GetReactor()->ModifyRegistration( this->reactable_, common::Bind(&HciHalHostRootcanal::incoming_packet_received, common::Unretained(this)), common::Bind(&HciHalHost::incoming_packet_received, common::Unretained(this)), common::Closure()); } } Loading Loading @@ -356,7 +508,7 @@ class HciHalHostRootcanal : public HciHal { } }; const ModuleFactory HciHal::Factory = ModuleFactory([]() { return new HciHalHostRootcanal(); }); const ModuleFactory HciHal::Factory = ModuleFactory([]() { return new HciHalHost(); }); } // namespace hal } // namespace bluetooth Loading
system/gd/Android.bp +2 −2 Original line number Diff line number Diff line Loading @@ -126,7 +126,7 @@ cc_defaults { host: { srcs: [ ":BluetoothBtaaSources_host", ":BluetoothHalSources_hci_rootcanal", ":BluetoothHalSources_hci_host", ":BluetoothOsSources_host", ], }, Loading Loading @@ -295,7 +295,7 @@ cc_test { }, host: { srcs: [ ":BluetoothHalTestSources_hci_rootcanal", ":BluetoothHalTestSources_hci_host", ":BluetoothOsTestSources_host", ], }, Loading
system/gd/docs/architecture/style_guide.md +4 −4 Original line number Diff line number Diff line Loading @@ -113,10 +113,10 @@ Root directory under Android tree: * hci_hal_android_hidl.cc: implementation of hci_hal.h using Android HIDL * hci_hal_android_hidl_test.cc: unit tests for the Android HIDL implementation * hci_hal_host_rootcanal.cc: implementation of hci_hal.h using root-canal emulator * hci_hal_host_rootcanal_test.cc: unit tests for the root-canal emulator implementation * hci_hal_host.cc: implementation of hci_hal.h using root-canal emulator or linux Bluetooth HCI socket * hci_hal_host_test.cc: unit tests for the socket based HAL (root-canal) emulator implementation * facade.proto: gRPC automation interface definition for this layer * facade.h/cc: an implementation of the above gRPC interface for the GD stack Loading
system/gd/facade/facade_main.cc +1 −1 Original line number Diff line number Diff line Loading @@ -35,7 +35,7 @@ #include "common/init_flags.h" #include "facade/grpc_root_server.h" #include "hal/hci_hal_host_rootcanal.h" #include "hal/hci_hal_host.h" #include "hal/snoop_logger.h" #include "os/log.h" #include "os/parameter_provider.h" Loading
system/gd/hal/Android.bp +4 −4 Original line number Diff line number Diff line Loading @@ -22,9 +22,9 @@ filegroup { } filegroup { name: "BluetoothHalSources_hci_rootcanal", name: "BluetoothHalSources_hci_host", srcs: [ "hci_hal_host_rootcanal.cc", "hci_hal_host.cc", ], } Loading @@ -36,9 +36,9 @@ filegroup { } filegroup { name: "BluetoothHalTestSources_hci_rootcanal", name: "BluetoothHalTestSources_hci_host", srcs: [ "hci_hal_host_rootcanal_test.cc", "hci_hal_host_test.cc", ], } Loading
system/gd/hal/hci_hal_host_rootcanal.cc→system/gd/hal/hci_hal_host.cc +174 −22 Original line number Diff line number Diff line Loading @@ -14,9 +14,10 @@ * limitations under the License. */ #include "hal/hci_hal_host_rootcanal.h" #include "hal/hci_hal_host.h" #include <netdb.h> #include <poll.h> #include <sys/socket.h> #include <sys/types.h> #include <unistd.h> Loading Loading @@ -48,7 +49,160 @@ constexpr uint8_t kHciEvtHeaderSize = 2; constexpr uint8_t kHciIsoHeaderSize = 4; constexpr int kBufSize = 1024 + 4 + 1; // DeviceProperties::acl_data_packet_size_ + ACL header + H4 header int ConnectToRootCanal(const std::string& server, int port) { #ifdef USE_LINUX_HCI_SOCKET constexpr uint8_t BTPROTO_HCI = 1; constexpr uint16_t HCI_CHANNEL_USER = 1; constexpr uint16_t HCI_CHANNEL_CONTROL = 3; constexpr uint16_t HCI_DEV_NONE = 0xffff; /* reference from <kernel>/include/net/bluetooth/mgmt.h */ #define MGMT_OP_INDEX_LIST 0x0003 #define MGMT_EV_INDEX_ADDED 0x0004 #define MGMT_EV_COMMAND_COMP 0x0001 #define MGMT_EV_SIZE_MAX 1024 #define WRITE_NO_INTR(fn) \ do { \ } while ((fn) == -1 && errno == EINTR) struct sockaddr_hci { sa_family_t hci_family; unsigned short hci_dev; unsigned short hci_channel; }; struct mgmt_pkt { uint16_t opcode; uint16_t index; uint16_t len; uint8_t data[MGMT_EV_SIZE_MAX]; } __attribute__((packed)); struct mgmt_event_read_index { uint16_t cc_opcode; uint8_t status; uint16_t num_intf; uint16_t index[0]; } __attribute__((packed)); int waitHciDev(int hci_interface) { struct sockaddr_hci addr; struct pollfd fds[1]; struct mgmt_pkt ev; int fd; int ret = 0; fd = socket(PF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); if (fd < 0) { LOG_ERROR("Bluetooth socket error: %s", strerror(errno)); return -1; } memset(&addr, 0, sizeof(addr)); addr.hci_family = AF_BLUETOOTH; addr.hci_dev = HCI_DEV_NONE; addr.hci_channel = HCI_CHANNEL_CONTROL; if (bind(fd, (struct sockaddr*)&addr, sizeof(addr)) < 0) { LOG_ERROR("HCI Channel Control: %s", strerror(errno)); close(fd); return -1; } fds[0].fd = fd; fds[0].events = POLLIN; /* Read Controller Index List Command */ ev.opcode = MGMT_OP_INDEX_LIST; ev.index = HCI_DEV_NONE; ev.len = 0; ssize_t wrote; WRITE_NO_INTR(wrote = write(fd, &ev, 6)); if (wrote != 6) { LOG_ERROR("Unable to write mgmt command: %s", strerror(errno)); close(fd); return -1; } /* validate mentioned hci interface is present and registered with sock system */ while (1) { int n; WRITE_NO_INTR(n = poll(fds, 1, -1)); if (n == -1) { LOG_ERROR("Poll error: %s", strerror(errno)); ret = -1; break; } else if (n == 0) { LOG_ERROR("Timeout, no HCI device detected"); ret = -1; break; } if (fds[0].revents & POLLIN) { WRITE_NO_INTR(n = read(fd, &ev, sizeof(struct mgmt_pkt))); if (n < 0) { LOG_ERROR("Error reading control channel: %s", strerror(errno)); ret = -1; break; } if (ev.opcode == MGMT_EV_INDEX_ADDED && ev.index == hci_interface) { close(fd); return -1; } else if (ev.opcode == MGMT_EV_COMMAND_COMP) { struct mgmt_event_read_index* cc; int i; cc = (struct mgmt_event_read_index*)ev.data; if (cc->cc_opcode != MGMT_OP_INDEX_LIST || cc->status != 0) continue; for (i = 0; i < cc->num_intf; i++) { if (cc->index[i] == hci_interface) { close(fd); return 0; } } } } } close(fd); return -1; } // Connect to Linux HCI socket int ConnectToSocket() { int socket_fd = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); if (socket_fd < 1) { LOG_ERROR("can't create socket: %s", strerror(errno)); return INVALID_FD; } int hci_interface = 0; // Assume we only have HCI 0 if (waitHciDev(hci_interface) != 0) { ::close(socket_fd); return INVALID_FD; } struct sockaddr_hci addr; memset(&addr, 0, sizeof(addr)); addr.hci_family = AF_BLUETOOTH; addr.hci_dev = hci_interface; addr.hci_channel = HCI_CHANNEL_USER; if (bind(socket_fd, (struct sockaddr*)&addr, sizeof(addr)) < 0) { LOG_ERROR("HCI Channel Control: %s", strerror(errno)); ::close(socket_fd); return INVALID_FD; } LOG_INFO("HCI device ready"); return socket_fd; } #else // Connect to root canal socket int ConnectToSocket() { auto* config = bluetooth::hal::HciHalHostRootcanalConfig::Get(); const std::string& server = config->GetServerAddress(); int port = config->GetPort(); int socket_fd = socket(AF_INET, SOCK_STREAM, 0); if (socket_fd < 1) { LOG_ERROR("can't create socket: %s", strerror(errno)); Loading Loading @@ -85,12 +239,13 @@ int ConnectToRootCanal(const std::string& server, int port) { } return socket_fd; } #endif } // namespace namespace bluetooth { namespace hal { class HciHalHostRootcanal : public HciHal { class HciHalHost : public HciHal { public: void registerIncomingPacketCallback(HciHalCallbacks* callback) override { std::lock_guard<std::mutex> lock(api_mutex_); Loading Loading @@ -119,7 +274,7 @@ class HciHalHostRootcanal : public HciHal { std::vector<uint8_t> packet = std::move(command); btsnoop_logger_->Capture(packet, SnoopLogger::Direction::OUTGOING, SnoopLogger::PacketType::CMD); packet.insert(packet.cbegin(), kH4Command); write_to_rootcanal_fd(packet); write_to_fd(packet); } void sendAclData(HciPacket data) override { Loading @@ -128,7 +283,7 @@ class HciHalHostRootcanal : public HciHal { std::vector<uint8_t> packet = std::move(data); btsnoop_logger_->Capture(packet, SnoopLogger::Direction::OUTGOING, SnoopLogger::PacketType::ACL); packet.insert(packet.cbegin(), kH4Acl); write_to_rootcanal_fd(packet); write_to_fd(packet); } void sendScoData(HciPacket data) override { Loading @@ -137,7 +292,7 @@ class HciHalHostRootcanal : public HciHal { std::vector<uint8_t> packet = std::move(data); btsnoop_logger_->Capture(packet, SnoopLogger::Direction::OUTGOING, SnoopLogger::PacketType::SCO); packet.insert(packet.cbegin(), kH4Sco); write_to_rootcanal_fd(packet); write_to_fd(packet); } void sendIsoData(HciPacket data) override { Loading @@ -146,7 +301,7 @@ class HciHalHostRootcanal : public HciHal { std::vector<uint8_t> packet = std::move(data); btsnoop_logger_->Capture(packet, SnoopLogger::Direction::OUTGOING, SnoopLogger::PacketType::ISO); packet.insert(packet.cbegin(), kH4Iso); write_to_rootcanal_fd(packet); write_to_fd(packet); } protected: Loading @@ -157,25 +312,23 @@ class HciHalHostRootcanal : public HciHal { void Start() override { std::lock_guard<std::mutex> lock(api_mutex_); ASSERT(sock_fd_ == INVALID_FD); sock_fd_ = ConnectToRootCanal(config_->GetServerAddress(), config_->GetPort()); sock_fd_ = ConnectToSocket(); ASSERT(sock_fd_ != INVALID_FD); reactable_ = hci_incoming_thread_.GetReactor()->Register( sock_fd_, common::Bind(&HciHalHostRootcanal::incoming_packet_received, common::Unretained(this)), common::Closure()); sock_fd_, common::Bind(&HciHalHost::incoming_packet_received, common::Unretained(this)), common::Closure()); btsnoop_logger_ = GetDependency<SnoopLogger>(); LOG_INFO("Rootcanal HAL opened successfully"); LOG_INFO("HAL opened successfully"); } void Stop() override { std::lock_guard<std::mutex> lock(api_mutex_); LOG_INFO("Rootcanal HAL is closing"); LOG_INFO("HAL is closing"); if (reactable_ != nullptr) { hci_incoming_thread_.GetReactor()->Unregister(reactable_); LOG_INFO("Rootcanal HAL is stopping, start waiting for last callback"); LOG_INFO("HAL is stopping, start waiting for last callback"); // Wait up to 1 second for the last incoming packet callback to finish hci_incoming_thread_.GetReactor()->WaitForUnregisteredReactable(std::chrono::milliseconds(1000)); LOG_INFO("Rootcanal HAL is stopping, finished waiting for last callback"); LOG_INFO("HAL is stopping, finished waiting for last callback"); ASSERT(sock_fd_ != INVALID_FD); } reactable_ = nullptr; Loading @@ -185,13 +338,12 @@ class HciHalHostRootcanal : public HciHal { } ::close(sock_fd_); sock_fd_ = INVALID_FD; LOG_INFO("Rootcanal HAL is closed"); LOG_INFO("HAL is closed"); } private: // Held when APIs are called, NOT to be held during callbacks std::mutex api_mutex_; HciHalHostRootcanalConfig* config_ = HciHalHostRootcanalConfig::Get(); HciHalCallbacks* incoming_packet_callback_ = nullptr; std::mutex incoming_packet_callback_mutex_; int sock_fd_ = INVALID_FD; Loading @@ -201,14 +353,14 @@ class HciHalHostRootcanal : public HciHal { std::queue<std::vector<uint8_t>> hci_outgoing_queue_; SnoopLogger* btsnoop_logger_ = nullptr; void write_to_rootcanal_fd(HciPacket packet) { void write_to_fd(HciPacket packet) { // TODO: replace this with new queue when it's ready hci_outgoing_queue_.emplace(packet); if (hci_outgoing_queue_.size() == 1) { hci_incoming_thread_.GetReactor()->ModifyRegistration( reactable_, common::Bind(&HciHalHostRootcanal::incoming_packet_received, common::Unretained(this)), common::Bind(&HciHalHostRootcanal::send_packet_ready, common::Unretained(this))); common::Bind(&HciHalHost::incoming_packet_received, common::Unretained(this)), common::Bind(&HciHalHost::send_packet_ready, common::Unretained(this))); } } Loading @@ -223,7 +375,7 @@ class HciHalHostRootcanal : public HciHal { if (hci_outgoing_queue_.empty()) { this->hci_incoming_thread_.GetReactor()->ModifyRegistration( this->reactable_, common::Bind(&HciHalHostRootcanal::incoming_packet_received, common::Unretained(this)), common::Bind(&HciHalHost::incoming_packet_received, common::Unretained(this)), common::Closure()); } } Loading Loading @@ -356,7 +508,7 @@ class HciHalHostRootcanal : public HciHal { } }; const ModuleFactory HciHal::Factory = ModuleFactory([]() { return new HciHalHostRootcanal(); }); const ModuleFactory HciHal::Factory = ModuleFactory([]() { return new HciHalHost(); }); } // namespace hal } // namespace bluetooth