summaryrefslogtreecommitdiff
path: root/src/components/transport_manager/src
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/transport_manager/src')
-rw-r--r--src/components/transport_manager/src/bluetooth/bluetooth_connection_factory.cc5
-rw-r--r--src/components/transport_manager/src/bluetooth/bluetooth_device.cc4
-rw-r--r--src/components/transport_manager/src/bluetooth/bluetooth_device_scanner.cc4
-rw-r--r--src/components/transport_manager/src/bluetooth/bluetooth_transport_adapter.cc4
-rw-r--r--src/components/transport_manager/src/iap2_emulation/iap2_transport_adapter.cc12
-rw-r--r--src/components/transport_manager/src/tcp/network_interface_listener_impl.cc42
-rw-r--r--src/components/transport_manager/src/tcp/platform_specific/linux/platform_specific_network_interface_listener.cc673
-rw-r--r--src/components/transport_manager/src/tcp/platform_specific/qnx/platform_specific_network_interface_listener.cc38
-rw-r--r--src/components/transport_manager/src/tcp/tcp_client_listener.cc551
-rw-r--r--src/components/transport_manager/src/tcp/tcp_connection_factory.cc5
-rw-r--r--src/components/transport_manager/src/tcp/tcp_server_originated_socket_connection.cc2
-rw-r--r--src/components/transport_manager/src/tcp/tcp_transport_adapter.cc35
-rw-r--r--src/components/transport_manager/src/transport_adapter/transport_adapter_impl.cc38
-rw-r--r--src/components/transport_manager/src/transport_adapter/transport_adapter_listener_impl.cc21
-rw-r--r--src/components/transport_manager/src/transport_manager_impl.cc19
-rw-r--r--src/components/transport_manager/src/usb/libusb/usb_connection.cc4
-rw-r--r--src/components/transport_manager/src/usb/qnx/usb_connection.cc4
-rw-r--r--src/components/transport_manager/src/usb/usb_connection_factory.cc21
18 files changed, 1325 insertions, 157 deletions
diff --git a/src/components/transport_manager/src/bluetooth/bluetooth_connection_factory.cc b/src/components/transport_manager/src/bluetooth/bluetooth_connection_factory.cc
index 0d8a77c88f..62615cb30f 100644
--- a/src/components/transport_manager/src/bluetooth/bluetooth_connection_factory.cc
+++ b/src/components/transport_manager/src/bluetooth/bluetooth_connection_factory.cc
@@ -37,7 +37,6 @@
#include "transport_manager/bluetooth/bluetooth_connection_factory.h"
#include "transport_manager/bluetooth/bluetooth_socket_connection.h"
#include "utils/logger.h"
-#include "utils/make_shared.h"
namespace transport_manager {
namespace transport_adapter {
@@ -55,8 +54,8 @@ TransportAdapter::Error BluetoothConnectionFactory::Init() {
TransportAdapter::Error BluetoothConnectionFactory::CreateConnection(
const DeviceUID& device_uid, const ApplicationHandle& app_handle) {
LOG4CXX_AUTO_TRACE(logger_);
- utils::SharedPtr<BluetoothSocketConnection> connection =
- utils::MakeShared<BluetoothSocketConnection>(
+ std::shared_ptr<BluetoothSocketConnection> connection =
+ std::make_shared<BluetoothSocketConnection>(
device_uid, app_handle, controller_);
controller_->ConnectionCreated(connection, device_uid, app_handle);
TransportAdapter::Error error = connection->Start();
diff --git a/src/components/transport_manager/src/bluetooth/bluetooth_device.cc b/src/components/transport_manager/src/bluetooth/bluetooth_device.cc
index 038515170d..e7cc3d4f34 100644
--- a/src/components/transport_manager/src/bluetooth/bluetooth_device.cc
+++ b/src/components/transport_manager/src/bluetooth/bluetooth_device.cc
@@ -45,6 +45,7 @@
#include <sys/socket.h>
#include <algorithm>
+#include <iostream>
#include <limits>
#include "utils/logger.h"
@@ -56,7 +57,8 @@ bool BluetoothDevice::GetRfcommChannel(const ApplicationHandle app_handle,
uint8_t* channel_out) {
LOG4CXX_TRACE(logger_,
"enter. app_handle: " << app_handle
- << ", channel_out: " << channel_out);
+ << ", channel_out: " << std::hex
+ << reinterpret_cast<void*>(channel_out));
if (app_handle < 0 || app_handle > std::numeric_limits<uint8_t>::max()) {
LOG4CXX_TRACE(logger_,
"exit with FALSE. Condition: app_handle < 0 || app_handle > "
diff --git a/src/components/transport_manager/src/bluetooth/bluetooth_device_scanner.cc b/src/components/transport_manager/src/bluetooth/bluetooth_device_scanner.cc
index 743c95f2e6..75ea799ce8 100644
--- a/src/components/transport_manager/src/bluetooth/bluetooth_device_scanner.cc
+++ b/src/components/transport_manager/src/bluetooth/bluetooth_device_scanner.cc
@@ -262,8 +262,8 @@ void BluetoothDeviceScanner::CheckSDLServiceOnDevices(
deviceName[name_len - 1] = '\0';
}
- Device* bluetooth_device =
- new BluetoothDevice(bd_address, deviceName, sdl_rfcomm_channels[i]);
+ auto bluetooth_device = std::make_shared<BluetoothDevice>(
+ bd_address, deviceName, sdl_rfcomm_channels[i]);
if (bluetooth_device) {
LOG4CXX_INFO(logger_, "Bluetooth device created successfully");
discovered_devices->push_back(bluetooth_device);
diff --git a/src/components/transport_manager/src/bluetooth/bluetooth_transport_adapter.cc b/src/components/transport_manager/src/bluetooth/bluetooth_transport_adapter.cc
index 0f83f32c60..b373744f79 100644
--- a/src/components/transport_manager/src/bluetooth/bluetooth_transport_adapter.cc
+++ b/src/components/transport_manager/src/bluetooth/bluetooth_transport_adapter.cc
@@ -80,8 +80,8 @@ void BluetoothTransportAdapter::Store() const {
if (!device) { // device could have been disconnected
continue;
}
- utils::SharedPtr<BluetoothDevice> bluetooth_device =
- DeviceSptr::static_pointer_cast<BluetoothDevice>(device);
+ std::shared_ptr<BluetoothDevice> bluetooth_device =
+ std::static_pointer_cast<BluetoothDevice>(device);
Json::Value device_dictionary;
device_dictionary["name"] = bluetooth_device->name();
char address[18];
diff --git a/src/components/transport_manager/src/iap2_emulation/iap2_transport_adapter.cc b/src/components/transport_manager/src/iap2_emulation/iap2_transport_adapter.cc
index 6b7d44ea8d..31e997f3ba 100644
--- a/src/components/transport_manager/src/iap2_emulation/iap2_transport_adapter.cc
+++ b/src/components/transport_manager/src/iap2_emulation/iap2_transport_adapter.cc
@@ -69,6 +69,11 @@ DeviceType IAP2BluetoothEmulationTransportAdapter::GetDeviceType() const {
return IOS_BT;
}
+void IAP2BluetoothEmulationTransportAdapter::TransportConfigUpdated(
+ const TransportConfig& new_config) {
+ return;
+}
+
IAP2USBEmulationTransportAdapter::IAP2USBEmulationTransportAdapter(
const uint16_t port,
resumption::LastState& last_state,
@@ -78,6 +83,7 @@ IAP2USBEmulationTransportAdapter::IAP2USBEmulationTransportAdapter(
signal_handler_ = threads::CreateThread("iAP signal handler", delegate);
signal_handler_->start();
const auto result = mkfifo(out_signals_channel, mode);
+ UNUSED(result);
LOG4CXX_DEBUG(logger_, "Out signals channel creation result: " << result);
}
@@ -119,10 +125,16 @@ DeviceType IAP2USBEmulationTransportAdapter::GetDeviceType() const {
return IOS_USB;
}
+void IAP2USBEmulationTransportAdapter::TransportConfigUpdated(
+ const TransportConfig& new_config) {
+ return;
+}
+
IAP2USBEmulationTransportAdapter::IAPSignalHandlerDelegate::
IAPSignalHandlerDelegate(IAP2USBEmulationTransportAdapter& adapter)
: adapter_(adapter), run_flag_(true), in_(0) {
const auto result = mkfifo(in_signals_channel, mode);
+ UNUSED(result);
LOG4CXX_DEBUG(logger_, "In signals channel creation result: " << result);
}
diff --git a/src/components/transport_manager/src/tcp/network_interface_listener_impl.cc b/src/components/transport_manager/src/tcp/network_interface_listener_impl.cc
new file mode 100644
index 0000000000..85c479134d
--- /dev/null
+++ b/src/components/transport_manager/src/tcp/network_interface_listener_impl.cc
@@ -0,0 +1,42 @@
+#include "transport_manager/tcp/network_interface_listener_impl.h"
+#include "platform_specific_network_interface_listener_impl.h"
+
+namespace transport_manager {
+namespace transport_adapter {
+
+CREATE_LOGGERPTR_GLOBAL(logger_, "TransportManager")
+
+NetworkInterfaceListenerImpl::NetworkInterfaceListenerImpl(
+ TcpClientListener* tcp_client_listener,
+ const std::string designated_interface)
+ : platform_specific_impl_(new PlatformSpecificNetworkInterfaceListener(
+ tcp_client_listener, designated_interface)) {
+ LOG4CXX_AUTO_TRACE(logger_);
+}
+
+NetworkInterfaceListenerImpl::~NetworkInterfaceListenerImpl() {
+ LOG4CXX_AUTO_TRACE(logger_);
+}
+
+bool NetworkInterfaceListenerImpl::Init() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ return platform_specific_impl_->Init();
+}
+
+void NetworkInterfaceListenerImpl::Deinit() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ platform_specific_impl_->Deinit();
+}
+
+bool NetworkInterfaceListenerImpl::Start() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ return platform_specific_impl_->Start();
+}
+
+bool NetworkInterfaceListenerImpl::Stop() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ return platform_specific_impl_->Stop();
+}
+
+} // namespace transport_adapter
+} // namespace transport_manager
diff --git a/src/components/transport_manager/src/tcp/platform_specific/linux/platform_specific_network_interface_listener.cc b/src/components/transport_manager/src/tcp/platform_specific/linux/platform_specific_network_interface_listener.cc
new file mode 100644
index 0000000000..047d43b7bf
--- /dev/null
+++ b/src/components/transport_manager/src/tcp/platform_specific/linux/platform_specific_network_interface_listener.cc
@@ -0,0 +1,673 @@
+#include "transport_manager/tcp/platform_specific/linux/platform_specific_network_interface_listener_impl.h"
+
+#include <arpa/inet.h>
+#include <asm/types.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <ifaddrs.h>
+#include <unistd.h>
+#include <net/if.h>
+#include <sys/types.h>
+#include <sys/select.h>
+#include <sys/socket.h>
+
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+
+#include "transport_manager/tcp/tcp_client_listener.h"
+#include "utils/logger.h"
+#include "utils/threads/thread.h"
+
+namespace transport_manager {
+namespace transport_adapter {
+
+CREATE_LOGGERPTR_GLOBAL(logger_, "TransportManager")
+
+static std::string GetInterfaceName(unsigned int if_index);
+static bool SetNonblocking(int s);
+
+bool InterfaceStatus::IsAvailable() const {
+ // check if the interface is UP and RUNNING
+ return ((flags_ & IFF_UP) > 0) && ((flags_ & IFF_RUNNING) > 0);
+}
+
+bool InterfaceStatus::IsLoopback() const {
+ return flags_ & IFF_LOOPBACK;
+}
+
+bool InterfaceStatus::HasIPAddress() const {
+ return has_ipv4_ || has_ipv6_;
+}
+
+std::string InterfaceStatus::GetIPv4Address() const {
+ char buf[INET_ADDRSTRLEN] = "";
+ if (has_ipv4_ && IsAvailable()) {
+ inet_ntop(AF_INET, &ipv4_address_, buf, sizeof(buf));
+ }
+ return std::string(buf);
+}
+
+std::string InterfaceStatus::GetIPv6Address() const {
+ char buf[INET6_ADDRSTRLEN] = "";
+ if (has_ipv6_ && IsAvailable()) {
+ inet_ntop(AF_INET6, &ipv6_address_, buf, sizeof(buf));
+ }
+ return std::string(buf);
+}
+
+void InterfaceStatus::SetIPv4Address(struct in_addr* addr) {
+ if (addr == NULL) {
+ has_ipv4_ = false;
+ } else {
+ ipv4_address_ = *addr;
+ has_ipv4_ = true;
+ }
+}
+
+void InterfaceStatus::SetIPv6Address(struct in6_addr* addr) {
+ if (addr == NULL) {
+ has_ipv6_ = false;
+ } else {
+ ipv6_address_ = *addr;
+ has_ipv6_ = true;
+ }
+}
+
+PlatformSpecificNetworkInterfaceListener::
+ PlatformSpecificNetworkInterfaceListener(
+ TcpClientListener* tcp_client_listener,
+ const std::string designated_interface)
+ : tcp_client_listener_(tcp_client_listener)
+ , designated_interface_(designated_interface)
+ , selected_interface_("")
+ , notified_ipv4_addr_("")
+ , notified_ipv6_addr_("")
+ , socket_(-1)
+#ifdef BUILD_TESTS
+ , testing_(false)
+#endif // BUILD_TESTS
+{
+ pipe_fds_[0] = pipe_fds_[1] = -1;
+ thread_ = threads::CreateThread("PlatformSpecificNetworkInterfaceListener",
+ new ListenerThreadDelegate(this));
+}
+
+PlatformSpecificNetworkInterfaceListener::
+ ~PlatformSpecificNetworkInterfaceListener() {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ Stop();
+ Deinit();
+
+ delete thread_->delegate();
+ threads::DeleteThread(thread_);
+}
+
+bool PlatformSpecificNetworkInterfaceListener::Init() {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ if (socket_ >= 0) {
+ LOG4CXX_WARN(logger_, "Network interface listener is already initialized");
+ return false;
+ }
+
+ socket_ = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
+ if (socket_ == -1) {
+ LOG4CXX_ERROR_WITH_ERRNO(logger_, "Failed to create netlink socket");
+ return false;
+ }
+
+ if (!SetNonblocking(socket_)) {
+ LOG4CXX_WARN(logger_, "Failed to configure netlink socket to non-blocking");
+ }
+
+ struct sockaddr_nl addr;
+ memset(&addr, 0, sizeof(addr));
+ addr.nl_family = AF_NETLINK;
+ addr.nl_pad = 0;
+ addr.nl_pid = 0;
+ addr.nl_groups = RTMGRP_LINK | RTMGRP_IPV4_IFADDR | RTMGRP_IPV6_IFADDR;
+
+ if (bind(socket_, reinterpret_cast<sockaddr*>(&addr), sizeof(addr)) != 0) {
+ LOG4CXX_ERROR_WITH_ERRNO(logger_, "Failed to bind netlink socket");
+ close(socket_);
+ socket_ = -1;
+ return false;
+ }
+
+ if (pipe(pipe_fds_) != 0) {
+ LOG4CXX_ERROR_WITH_ERRNO(logger_, "Failed to create internal pipe");
+ close(socket_);
+ socket_ = -1;
+ return false;
+ }
+
+ if (!SetNonblocking(pipe_fds_[0])) {
+ LOG4CXX_WARN(logger_, "Failed to configure pipe to non-blocking");
+ }
+
+ return true;
+}
+
+void PlatformSpecificNetworkInterfaceListener::Deinit() {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ if (socket_ >= 0) {
+ close(socket_);
+ socket_ = -1;
+ }
+ if (pipe_fds_[1] >= 0) {
+ close(pipe_fds_[1]);
+ pipe_fds_[1] = -1;
+ }
+ if (pipe_fds_[0] >= 0) {
+ close(pipe_fds_[0]);
+ pipe_fds_[0] = -1;
+ }
+}
+
+bool PlatformSpecificNetworkInterfaceListener::Start() {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ if (socket_ < 0) {
+ LOG4CXX_WARN(logger_, "Interface listener is not initialized");
+ return false;
+ }
+
+ if (thread_->is_running()) {
+ LOG4CXX_WARN(logger_, "Interface listener is already started");
+ return false;
+ }
+
+ if (!thread_->start()) {
+ LOG4CXX_ERROR(logger_, "Failed to start interface listener");
+ return false;
+ }
+
+ LOG4CXX_INFO(logger_, "Network interface listener started");
+ return true;
+}
+
+bool PlatformSpecificNetworkInterfaceListener::Stop() {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ if (!thread_->is_running()) {
+ LOG4CXX_DEBUG(logger_, "interface listener is not running");
+ return false;
+ }
+
+ thread_->join();
+
+ LOG4CXX_INFO(logger_, "Network interface listener stopped");
+ return true;
+}
+
+void PlatformSpecificNetworkInterfaceListener::Loop() {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ // Initialize status_table_ by acquiring a list of interfaces and their
+ // current statuses. Also we will notify an event to the listener if IP
+ // address is already available.
+ InitializeStatus();
+ NotifyIPAddresses();
+
+ // I am not sure required buffer size for netlink data structures. Most of
+ // implementation I found online uses 4096 so I followed them.
+ char buf[4096];
+ fd_set rfds;
+
+ while (1) {
+ FD_ZERO(&rfds);
+ FD_SET(socket_, &rfds);
+ FD_SET(pipe_fds_[0], &rfds);
+ int nfds = socket_ > pipe_fds_[0] ? socket_ : pipe_fds_[0];
+
+ // wait for some data from netlink socket (socket_) and our internal pipe
+ int ret = select(nfds + 1, &rfds, NULL, NULL, NULL);
+ if (ret < 0) {
+ if (errno == EINTR) {
+ continue;
+ } else {
+ LOG4CXX_WARN(logger_,
+ "select failed for netlink. Aborting interface listener.");
+ break;
+ }
+ }
+
+ // Received data from internal pipe, indicating StopLoop() is called.
+ // We'll break the while() loop and eventually exit this thread.
+ if (FD_ISSET(pipe_fds_[0], &rfds)) {
+ ret = read(pipe_fds_[0], buf, sizeof(buf));
+ if (ret < 0) {
+ if (errno != EINTR && errno != EAGAIN && errno != EWOULDBLOCK) {
+ LOG4CXX_WARN(
+ logger_,
+ "Failed to read from pipe. Aborting interface listener.");
+ break;
+ }
+ } else if (ret == 0) {
+ LOG4CXX_WARN(logger_,
+ "Pipe disconnected. Aborting interface listener.");
+ break;
+ } else {
+ LOG4CXX_DEBUG(logger_, "received terminating event through pipe");
+ break;
+ }
+ }
+
+#ifdef BUILD_TESTS
+ if (testing_) { // don't enable events from network interface while testing
+ continue;
+ }
+#endif // BUILD_TESTS
+
+ // received data from netlink socket
+ if (FD_ISSET(socket_, &rfds)) {
+ ret = recv(socket_, buf, sizeof(buf), 0);
+ if (ret < 0) {
+ if (errno != EINTR && errno != EAGAIN && errno != EWOULDBLOCK) {
+ LOG4CXX_WARN(logger_,
+ "Failed to read from netlink socket. Aborting interface "
+ "listener.");
+ break;
+ }
+ } else if (ret == 0) {
+ LOG4CXX_WARN(
+ logger_,
+ "Netlink socket disconnected. Aborting interface listener.");
+ break;
+ } else {
+ struct nlmsghdr* header = reinterpret_cast<struct nlmsghdr*>(buf);
+ int len = ret;
+
+ // Parse the stream. We may receive multiple (header + data) pairs at a
+ // time so we use for-loop to go through.
+ for (; NLMSG_OK(header, len); header = NLMSG_NEXT(header, len)) {
+ if (header->nlmsg_type == NLMSG_ERROR) {
+ LOG4CXX_WARN(logger_, "received error event from netlink");
+ break;
+ }
+
+ std::vector<EventParam> params;
+
+ if (header->nlmsg_type == RTM_NEWLINK ||
+ header->nlmsg_type == RTM_DELLINK) {
+ // For these events, data part contains an ifinfomsg struct and a
+ // series of rtattr structures. See rtnetlink(7).
+ // We are only interested in interface index and flags.
+ struct ifinfomsg* ifinfo_msg =
+ reinterpret_cast<struct ifinfomsg*>(NLMSG_DATA(header));
+ EventParam param(ifinfo_msg->ifi_index, ifinfo_msg->ifi_flags);
+ params.push_back(param);
+
+ } else if (header->nlmsg_type == RTM_NEWADDR ||
+ header->nlmsg_type == RTM_DELADDR) {
+ // For these events, data part contains an ifaddrmsg struct and
+ // optionally some rtattr structures. We'll extract IP address(es)
+ // from them.
+ struct ifaddrmsg* ifaddr_msg =
+ reinterpret_cast<struct ifaddrmsg*>(NLMSG_DATA(header));
+ unsigned int size = IFA_PAYLOAD(header);
+ params = ParseIFAddrMessage(ifaddr_msg, size);
+
+ } else {
+ continue;
+ }
+
+ // update status_table_ based on received data
+ UpdateStatus(header->nlmsg_type, params);
+ }
+ }
+
+ // notify the listener if necessary
+ NotifyIPAddresses();
+ }
+ }
+}
+
+bool PlatformSpecificNetworkInterfaceListener::StopLoop() {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ LOG4CXX_INFO(logger_, "Stopping network interface listener");
+
+ if (pipe_fds_[1] < 0) {
+ LOG4CXX_WARN(logger_, "StopLoop called in invalid state");
+ return false;
+ }
+
+ char dummy[1] = {0};
+ int ret = write(pipe_fds_[1], dummy, sizeof(dummy));
+ if (ret <= 0) {
+ LOG4CXX_WARN_WITH_ERRNO(
+ logger_, "Failed to send stop message to interface listener");
+ return false;
+ }
+
+ return true;
+}
+
+bool PlatformSpecificNetworkInterfaceListener::InitializeStatus() {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+#ifdef BUILD_TESTS
+ if (testing_) {
+ // don't actually call getifaddrs()
+ return true;
+ }
+#endif // BUILD_TESTS
+
+ struct ifaddrs* if_list, *interface;
+ if (getifaddrs(&if_list) != 0) {
+ LOG4CXX_WARN(logger_,
+ "getifaddr failed, interface status won't be available until "
+ "a change occurs");
+ return false;
+ }
+
+ // clear existing table
+ status_table_.clear();
+
+ for (interface = if_list; interface != NULL;
+ interface = interface->ifa_next) {
+ if (interface->ifa_name == NULL || interface->ifa_name[0] == '\0') {
+ continue;
+ }
+ if (interface->ifa_addr == NULL) {
+ continue;
+ }
+
+ std::string ifname(interface->ifa_name);
+ InterfaceStatus& status = status_table_[ifname];
+
+ switch (interface->ifa_addr->sa_family) {
+ case AF_INET: {
+ struct sockaddr_in* addr =
+ reinterpret_cast<struct sockaddr_in*>(interface->ifa_addr);
+ status.SetIPv4Address(&addr->sin_addr);
+ break;
+ }
+ case AF_INET6: {
+ struct sockaddr_in6* addr =
+ reinterpret_cast<struct sockaddr_in6*>(interface->ifa_addr);
+ status.SetIPv6Address(&addr->sin6_addr);
+ break;
+ }
+ default:
+ continue;
+ }
+ status.SetFlags(interface->ifa_flags);
+ }
+
+ freeifaddrs(if_list);
+
+ LOG4CXX_DEBUG(logger_, "Successfully acquired network interface status");
+ DumpTable();
+ return true;
+}
+
+bool PlatformSpecificNetworkInterfaceListener::UpdateStatus(
+ uint16_t type, std::vector<EventParam>& params) {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ for (std::vector<EventParam>::iterator it = params.begin();
+ it != params.end();
+ ++it) {
+ std::string ifname = GetInterfaceName(it->if_index);
+ if (ifname.empty()) {
+ continue;
+ }
+
+ InterfaceStatus& status = status_table_[ifname];
+
+ switch (type) {
+ case RTM_NEWLINK: {
+ LOG4CXX_DEBUG(logger_,
+ "netlink event: interface " << ifname
+ << " created or updated");
+ status.SetFlags(it->flags);
+ break;
+ }
+ case RTM_DELLINK:
+ LOG4CXX_DEBUG(logger_,
+ "netlink event: interface " << ifname << " removed");
+ status_table_.erase(ifname);
+ break;
+ case RTM_NEWADDR: {
+ sockaddr* addr = reinterpret_cast<sockaddr*>(&it->address);
+ if (addr->sa_family == AF_INET) {
+ sockaddr_in* addr_in = reinterpret_cast<sockaddr_in*>(addr);
+ status.SetIPv4Address(&addr_in->sin_addr);
+ LOG4CXX_DEBUG(logger_,
+ "netlink event: IPv4 address of interface "
+ << ifname << " updated to "
+ << status.GetIPv4Address());
+ } else if (addr->sa_family == AF_INET6) {
+ sockaddr_in6* addr_in6 = reinterpret_cast<sockaddr_in6*>(addr);
+ status.SetIPv6Address(&addr_in6->sin6_addr);
+ LOG4CXX_DEBUG(logger_,
+ "netlink event: IPv6 address of interface "
+ << ifname << " updated to "
+ << status.GetIPv6Address());
+ }
+ break;
+ }
+ case RTM_DELADDR: {
+ sockaddr* addr = reinterpret_cast<sockaddr*>(&it->address);
+ if (addr->sa_family == AF_INET) {
+ LOG4CXX_DEBUG(logger_,
+ "netlink event: IPv4 address of interface "
+ << ifname << " removed");
+ status.SetIPv4Address(NULL);
+ } else if (addr->sa_family == AF_INET6) {
+ LOG4CXX_DEBUG(logger_,
+ "netlink event: IPv6 address of interface "
+ << ifname << " removed");
+ status.SetIPv6Address(NULL);
+ }
+ break;
+ }
+ default:
+ LOG4CXX_WARN(logger_, "Unsupported netlink event (" << type << ")");
+ break;
+ }
+ }
+ return true;
+}
+
+void PlatformSpecificNetworkInterfaceListener::NotifyIPAddresses() {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ std::string ipv4_addr;
+ std::string ipv6_addr;
+ const std::string interface_name = SelectInterface();
+
+ // note that if interface_name is empty (i.e. no interface is selected),
+ // the IP addresses will be empty
+ if (!interface_name.empty()) {
+ InterfaceStatusTable::iterator it = status_table_.find(interface_name);
+ if (status_table_.end() != it) {
+ InterfaceStatus& status = it->second;
+ ipv4_addr = status.GetIPv4Address();
+ ipv6_addr = status.GetIPv6Address();
+ }
+ }
+
+ if (notified_ipv4_addr_ != ipv4_addr || notified_ipv6_addr_ != ipv6_addr) {
+ LOG4CXX_INFO(logger_,
+ "IP address updated: \"" << notified_ipv4_addr_ << "\" -> \""
+ << ipv4_addr << "\", \""
+ << notified_ipv6_addr_ << "\" -> \""
+ << ipv6_addr << "\"");
+
+ notified_ipv4_addr_ = ipv4_addr;
+ notified_ipv6_addr_ = ipv6_addr;
+
+ tcp_client_listener_->OnIPAddressUpdated(notified_ipv4_addr_,
+ notified_ipv6_addr_);
+ }
+}
+
+const std::string PlatformSpecificNetworkInterfaceListener::SelectInterface() {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ if (!designated_interface_.empty()) {
+ return designated_interface_;
+ }
+
+ InterfaceStatusTable::iterator it;
+
+ if (!selected_interface_.empty()) {
+ // if current network interface is still available and has IP address, then
+ // we use it
+ it = status_table_.find(selected_interface_);
+ if (it != status_table_.end()) {
+ InterfaceStatus& status = it->second;
+ if (status.IsAvailable() && status.HasIPAddress()) {
+ return selected_interface_;
+ }
+ }
+ }
+
+ // pick a network interface that has IP address
+ for (it = status_table_.begin(); it != status_table_.end(); ++it) {
+ InterfaceStatus& status = it->second;
+ // ignore loopback interfaces
+ if (status.IsLoopback()) {
+ continue;
+ }
+ // if the interface has to be UP and RUNNING, and must have an IP address
+ if (!(status.IsAvailable() && status.HasIPAddress())) {
+ continue;
+ }
+
+ selected_interface_ = it->first;
+ LOG4CXX_DEBUG(logger_,
+ "selecting network interface: " << selected_interface_);
+ return selected_interface_;
+ }
+
+ selected_interface_ = "";
+ return selected_interface_;
+}
+
+std::vector<PlatformSpecificNetworkInterfaceListener::EventParam>
+PlatformSpecificNetworkInterfaceListener::ParseIFAddrMessage(
+ struct ifaddrmsg* message, unsigned int size) {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ std::vector<EventParam> params;
+
+ // Iterate through rtattr structs. (The first one can be acquired through
+ // IFA_RTA() macro)
+ for (struct rtattr* attr = IFA_RTA(message); RTA_OK(attr, size);
+ attr = RTA_NEXT(attr, size)) {
+ if (!(attr->rta_type == IFA_LOCAL || attr->rta_type == IFA_ADDRESS)) {
+ continue;
+ }
+
+ EventParam param(message->ifa_index);
+
+ if (message->ifa_family == AF_INET) {
+ // make sure the size of data is >= 4 bytes
+ if (RTA_PAYLOAD(attr) < sizeof(struct in_addr)) {
+ LOG4CXX_DEBUG(logger_,
+ "Invalid netlink event: insufficient IPv4 address data");
+ continue;
+ }
+
+ // Data part of rtattr contains IPv4 address. Copy it to param.address
+ struct in_addr* ipv4_addr =
+ reinterpret_cast<struct in_addr*>(RTA_DATA(attr));
+
+ struct sockaddr_in* sockaddr =
+ reinterpret_cast<struct sockaddr_in*>(&param.address);
+ sockaddr->sin_family = AF_INET;
+ sockaddr->sin_addr = *ipv4_addr;
+
+ } else if (message->ifa_family == AF_INET6) {
+ // make sure the size of data is >= 16 bytes
+ if (RTA_PAYLOAD(attr) < sizeof(struct in6_addr)) {
+ LOG4CXX_DEBUG(logger_,
+ "Invalid netlink event: insufficient IPv6 address data");
+ continue;
+ }
+
+ // Data part of rtattr contains IPv6 address. Copy it to param.address
+ struct in6_addr* ipv6_addr =
+ reinterpret_cast<struct in6_addr*>(RTA_DATA(attr));
+
+ struct sockaddr_in6* sockaddr =
+ reinterpret_cast<struct sockaddr_in6*>(&param.address);
+ sockaddr->sin6_family = AF_INET6;
+ sockaddr->sin6_addr = *ipv6_addr;
+
+ } else {
+ LOG4CXX_WARN(logger_,
+ "Unsupported family (" << message->ifa_family << ")");
+ continue;
+ }
+
+ params.push_back(param);
+ }
+
+ return params;
+}
+
+void PlatformSpecificNetworkInterfaceListener::DumpTable() const {
+ LOG4CXX_DEBUG(logger_,
+ "Number of network interfaces: " << status_table_.size());
+
+ for (auto it = status_table_.begin(); it != status_table_.end(); ++it) {
+ const std::string ifname = it->first;
+ const InterfaceStatus& status = it->second;
+ UNUSED(status);
+
+ LOG4CXX_DEBUG(
+ logger_,
+ " " << ifname << " : flags=" << status.GetFlags()
+ << " : available: " << (status.IsAvailable() ? "yes" : "no")
+ << " IPv4: " << status.GetIPv4Address()
+ << " IPv6: " << status.GetIPv6Address()
+ << (status.IsLoopback() ? " (loopback)" : ""));
+ }
+}
+
+PlatformSpecificNetworkInterfaceListener::ListenerThreadDelegate::
+ ListenerThreadDelegate(PlatformSpecificNetworkInterfaceListener* parent)
+ : parent_(parent) {}
+
+void PlatformSpecificNetworkInterfaceListener::ListenerThreadDelegate::
+ threadMain() {
+ parent_->Loop();
+}
+
+void PlatformSpecificNetworkInterfaceListener::ListenerThreadDelegate::
+ exitThreadMain() {
+ parent_->StopLoop();
+}
+
+static std::string GetInterfaceName(unsigned int if_index) {
+ char buf[IFNAMSIZ + 1] = "";
+ if_indextoname(if_index, buf);
+ return std::string(buf);
+}
+
+static bool SetNonblocking(int s) {
+ int prev_flag = fcntl(s, F_GETFL, 0);
+ if (prev_flag == -1) {
+ LOG4CXX_ERROR_WITH_ERRNO(logger_, "Failed to acquire socket flag");
+ return false;
+ }
+
+ int ret = fcntl(s, F_SETFL, prev_flag | O_NONBLOCK);
+ if (ret == -1) {
+ LOG4CXX_ERROR_WITH_ERRNO(logger_,
+ "Failed to configure socket to non-blocking");
+ return false;
+ }
+
+ return true;
+}
+
+} // namespace transport_adapter
+} // namespace transport_manager
diff --git a/src/components/transport_manager/src/tcp/platform_specific/qnx/platform_specific_network_interface_listener.cc b/src/components/transport_manager/src/tcp/platform_specific/qnx/platform_specific_network_interface_listener.cc
new file mode 100644
index 0000000000..15b3814999
--- /dev/null
+++ b/src/components/transport_manager/src/tcp/platform_specific/qnx/platform_specific_network_interface_listener.cc
@@ -0,0 +1,38 @@
+#include "transport_manager/tcp/platform_specific/qnx/platform_specific_network_interface_listener_impl.h"
+
+namespace transport_manager {
+namespace transport_adapter {
+
+CREATE_LOGGERPTR_GLOBAL(logger_, "TransportManager")
+
+PlatformSpecificNetworkInterfaceListener::
+ PlatformSpecificNetworkInterfaceListener(
+ TcpClientListener* tcp_client_listener,
+ const std::string designated_interface) {}
+
+PlatformSpecificNetworkInterfaceListener::
+ ~PlatformSpecificNetworkInterfaceListener() {
+ LOG4CXX_AUTO_TRACE(logger_);
+}
+
+bool PlatformSpecificNetworkInterfaceListener::Init() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ return true;
+}
+
+void PlatformSpecificNetworkInterfaceListener::Deinit() {
+ LOG4CXX_AUTO_TRACE(logger_);
+}
+
+bool PlatformSpecificNetworkInterfaceListener::Start() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ return true;
+}
+
+bool PlatformSpecificNetworkInterfaceListener::Stop() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ return true;
+}
+
+} // namespace transport_adapter
+} // namespace transport_manager
diff --git a/src/components/transport_manager/src/tcp/tcp_client_listener.cc b/src/components/transport_manager/src/tcp/tcp_client_listener.cc
index 207149eb8c..9f2597f0a7 100644
--- a/src/components/transport_manager/src/tcp/tcp_client_listener.cc
+++ b/src/components/transport_manager/src/tcp/tcp_client_listener.cc
@@ -36,11 +36,14 @@
#include <memory.h>
#include <signal.h>
#include <errno.h>
+#include <fcntl.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/types.h>
+#include <sys/select.h>
#include <sys/sysctl.h>
#include <sys/socket.h>
+#include <ifaddrs.h>
#ifdef __linux__
#include <linux/tcp.h>
#else // __linux__
@@ -53,9 +56,10 @@
#include <sstream>
#include "utils/logger.h"
-#include "utils/make_shared.h"
+
#include "utils/threads/thread.h"
#include "transport_manager/transport_adapter/transport_adapter_controller.h"
+#include "transport_manager/tcp/network_interface_listener_impl.h"
#include "transport_manager/tcp/tcp_device.h"
#include "transport_manager/tcp/tcp_socket_connection.h"
@@ -64,72 +68,88 @@ namespace transport_adapter {
CREATE_LOGGERPTR_GLOBAL(logger_, "TransportManager")
+static bool SetNonblocking(int s);
+
+#ifdef BUILD_TESTS
+bool TcpClientListener::testing_ = false;
+#endif // BUILD_TESTS
+
TcpClientListener::TcpClientListener(TransportAdapterController* controller,
const uint16_t port,
- const bool enable_keepalive)
+ const bool enable_keepalive,
+ const std::string designated_interface)
: port_(port)
, enable_keepalive_(enable_keepalive)
, controller_(controller)
+ , initialized_(false)
+ , started_(false)
, thread_(0)
, socket_(-1)
- , thread_stop_requested_(false) {
+ , thread_stop_requested_(false)
+ , designated_interface_(designated_interface) {
+ pipe_fds_[0] = pipe_fds_[1] = -1;
thread_ = threads::CreateThread("TcpClientListener",
new ListeningThreadDelegate(this));
+ interface_listener_ =
+ new NetworkInterfaceListenerImpl(this, designated_interface);
}
TransportAdapter::Error TcpClientListener::Init() {
LOG4CXX_AUTO_TRACE(logger_);
thread_stop_requested_ = false;
- socket_ = socket(AF_INET, SOCK_STREAM, 0);
- if (-1 == socket_) {
- LOG4CXX_ERROR_WITH_ERRNO(logger_, "Failed to create socket");
- return TransportAdapter::FAIL;
- }
-
- sockaddr_in server_address = {0};
- server_address.sin_family = AF_INET;
- server_address.sin_port = htons(port_);
- server_address.sin_addr.s_addr = INADDR_ANY;
-
- int optval = 1;
- if (0 !=
- setsockopt(socket_, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval))) {
- LOG4CXX_WARN_WITH_ERRNO(logger_, "setsockopt SO_REUSEADDR failed");
+ if (!IsListeningOnSpecificInterface()) {
+ // Network interface is not specified. We will listen on all interfaces
+ // using INADDR_ANY. If socket creation fails, we will treat it an error.
+ socket_ = CreateIPv4ServerSocket(port_);
+ if (-1 == socket_) {
+ LOG4CXX_ERROR(logger_, "Failed to create TCP socket");
+ return TransportAdapter::FAIL;
+ }
+ } else {
+ // Network interface is specified and we wiill listen only on the interface.
+ // In this case, the server socket will be created once
+ // NetworkInterfaceListener notifies the interface's IP address.
+ LOG4CXX_INFO(logger_,
+ "TCP server socket will listen on "
+ << designated_interface_
+ << " once it has an IPv4 address.");
}
- if (bind(socket_,
- reinterpret_cast<sockaddr*>(&server_address),
- sizeof(server_address)) != 0) {
- LOG4CXX_ERROR_WITH_ERRNO(logger_, "bind() failed");
+ if (!interface_listener_->Init()) {
+ if (socket_ >= 0) {
+ close(socket_);
+ socket_ = -1;
+ }
return TransportAdapter::FAIL;
}
- const int kBacklog = 128;
- if (0 != listen(socket_, kBacklog)) {
- LOG4CXX_ERROR_WITH_ERRNO(logger_, "listen() failed");
- return TransportAdapter::FAIL;
- }
+ initialized_ = true;
return TransportAdapter::OK;
}
void TcpClientListener::Terminate() {
LOG4CXX_AUTO_TRACE(logger_);
- if (socket_ == -1) {
- LOG4CXX_WARN(logger_, "Socket has been closed");
+
+ if (!initialized_) {
return;
}
- if (shutdown(socket_, SHUT_RDWR) != 0) {
- LOG4CXX_ERROR_WITH_ERRNO(logger_, "Failed to shutdown socket");
- }
- if (close(socket_) != 0) {
- LOG4CXX_ERROR_WITH_ERRNO(logger_, "Failed to close socket");
+
+ if (!IsListeningOnSpecificInterface()) {
+ DestroyServerSocket(socket_);
+ socket_ = -1;
+ } else {
+ sync_primitives::AutoLock auto_lock(start_stop_lock_);
+ DestroyServerSocket(socket_);
+ socket_ = -1;
}
- socket_ = -1;
+
+ interface_listener_->Deinit();
+ initialized_ = false;
}
bool TcpClientListener::IsInitialised() const {
- return thread_;
+ return initialized_;
}
TcpClientListener::~TcpClientListener() {
@@ -138,6 +158,7 @@ TcpClientListener::~TcpClientListener() {
delete thread_->delegate();
threads::DeleteThread(thread_);
Terminate();
+ delete interface_listener_;
}
void SetKeepaliveOptions(const int fd) {
@@ -203,104 +224,152 @@ void SetKeepaliveOptions(const int fd) {
void TcpClientListener::Loop() {
LOG4CXX_AUTO_TRACE(logger_);
- while (!thread_stop_requested_) {
- sockaddr_in client_address;
- socklen_t client_address_size = sizeof(client_address);
- const int connection_fd = accept(
- socket_, (struct sockaddr*)&client_address, &client_address_size);
- if (thread_stop_requested_) {
- LOG4CXX_DEBUG(logger_, "thread_stop_requested_");
- close(connection_fd);
- break;
- }
+ fd_set rfds;
+ char dummy[16];
- if (connection_fd < 0) {
- LOG4CXX_ERROR_WITH_ERRNO(logger_, "accept() failed");
- continue;
- }
-
- if (AF_INET != client_address.sin_family) {
- LOG4CXX_DEBUG(logger_, "Address of connected client is invalid");
- close(connection_fd);
- continue;
+ while (!thread_stop_requested_) {
+ FD_ZERO(&rfds);
+ FD_SET(socket_, &rfds);
+ FD_SET(pipe_fds_[0], &rfds);
+ int nfds = socket_ > pipe_fds_[0] ? socket_ : pipe_fds_[0];
+
+ int ret = select(nfds + 1, &rfds, NULL, NULL, NULL);
+ if (ret < 0) {
+ if (errno == EINTR) {
+ continue;
+ } else {
+ LOG4CXX_WARN(logger_, "select failed for TCP server socket");
+ break;
+ }
}
- char device_name[32];
- strncpy(device_name,
- inet_ntoa(client_address.sin_addr),
- sizeof(device_name) / sizeof(device_name[0]));
- LOG4CXX_INFO(logger_, "Connected client " << device_name);
- LOG4CXX_INFO(logger_, "Port is: " << port_);
-
- if (enable_keepalive_) {
- SetKeepaliveOptions(connection_fd);
+ if (FD_ISSET(pipe_fds_[0], &rfds)) {
+ ret = read(pipe_fds_[0], dummy, sizeof(dummy));
+ if (ret < 0) {
+ if (errno != EINTR && errno != EAGAIN && errno != EWOULDBLOCK) {
+ LOG4CXX_WARN(
+ logger_,
+ "Failed to read from pipe, aborting TCP server socket loop.");
+ break;
+ }
+ } else if (ret == 0) {
+ LOG4CXX_WARN(logger_,
+ "Pipe disconnected, aborting TCP server socket loop.");
+ break;
+ } else {
+ LOG4CXX_DEBUG(logger_,
+ "received stop command of TCP server socket loop");
+ break;
+ }
}
- const auto device_uid =
- device_name + std::string(":") + std::to_string(port_);
+ if (FD_ISSET(socket_, &rfds)) {
+ sockaddr_in client_address;
+ socklen_t client_address_size = sizeof(client_address);
+ const int connection_fd = accept(
+ socket_, (struct sockaddr*)&client_address, &client_address_size);
+ if (thread_stop_requested_) {
+ LOG4CXX_DEBUG(logger_, "thread_stop_requested_");
+ close(connection_fd);
+ break;
+ }
+
+ if (connection_fd < 0) {
+ LOG4CXX_ERROR_WITH_ERRNO(logger_, "accept() failed");
+ continue;
+ }
+
+ if (AF_INET != client_address.sin_family) {
+ LOG4CXX_DEBUG(logger_, "Address of connected client is invalid");
+ close(connection_fd);
+ continue;
+ }
+
+ char device_name[32];
+ size_t size = sizeof(device_name) / sizeof(device_name[0]);
+ strncpy(device_name, inet_ntoa(client_address.sin_addr), size);
+
+ device_name[size - 1] = '\0';
+ LOG4CXX_INFO(logger_, "Connected client " << device_name);
+ LOG4CXX_INFO(logger_, "Port is: " << port_);
+
+ if (enable_keepalive_) {
+ SetKeepaliveOptions(connection_fd);
+ }
+
+ const auto device_uid =
+ device_name + std::string(":") + std::to_string(port_);
#if defined(BUILD_TESTS)
- TcpDevice* tcp_device =
- new TcpDevice(client_address.sin_addr.s_addr, device_uid, device_name);
+ auto tcp_device = std::make_shared<TcpDevice>(
+ client_address.sin_addr.s_addr, device_uid, device_name);
#else
- TcpDevice* tcp_device =
- new TcpDevice(client_address.sin_addr.s_addr, device_uid);
+ auto tcp_device = std::make_shared<TcpDevice>(
+ client_address.sin_addr.s_addr, device_uid);
#endif // BUILD_TESTS
- DeviceSptr device = controller_->AddDevice(tcp_device);
- tcp_device = static_cast<TcpDevice*>(device.get());
- const ApplicationHandle app_handle =
- tcp_device->AddIncomingApplication(connection_fd);
-
- utils::SharedPtr<TcpSocketConnection> connection =
- utils::MakeShared<TcpSocketConnection>(
- device->unique_device_id(), app_handle, controller_);
- controller_->ConnectionCreated(
- connection, device->unique_device_id(), app_handle);
- connection->set_socket(connection_fd);
- const TransportAdapter::Error error = connection->Start();
- if (TransportAdapter::OK != error) {
- LOG4CXX_ERROR(logger_,
- "TCP connection::Start() failed with error: " << error);
+ DeviceSptr device = controller_->AddDevice(tcp_device);
+ auto tcp_device_raw = static_cast<TcpDevice*>(device.get());
+ const ApplicationHandle app_handle =
+ tcp_device_raw->AddIncomingApplication(connection_fd);
+
+ std::shared_ptr<TcpSocketConnection> connection =
+ std::make_shared<TcpSocketConnection>(
+ device->unique_device_id(), app_handle, controller_);
+ controller_->ConnectionCreated(
+ connection, device->unique_device_id(), app_handle);
+ connection->set_socket(connection_fd);
+ const TransportAdapter::Error error = connection->Start();
+ if (TransportAdapter::OK != error) {
+ LOG4CXX_ERROR(logger_,
+ "TCP connection::Start() failed with error: " << error);
+ }
}
}
+
+ LOG4CXX_INFO(logger_, "TCP server socket loop is terminated.");
}
void TcpClientListener::StopLoop() {
LOG4CXX_AUTO_TRACE(logger_);
+ if (pipe_fds_[1] < 0) {
+ LOG4CXX_WARN(logger_, "StopLoop called in invalid state");
+ return;
+ }
+
thread_stop_requested_ = true;
- // We need to connect to the listening socket to unblock accept() call
- int byesocket = socket(AF_INET, SOCK_STREAM, 0);
- sockaddr_in server_address = {0};
- server_address.sin_family = AF_INET;
- server_address.sin_port = htons(port_);
- server_address.sin_addr.s_addr = INADDR_ANY;
- if (0 != connect(byesocket,
- reinterpret_cast<sockaddr*>(&server_address),
- sizeof(server_address))) {
- LOG4CXX_WARN_WITH_ERRNO(logger_, "Failed to connect byesocket");
- } else {
- // Can only shutdown socket if connected
- if (0 != shutdown(byesocket, SHUT_RDWR)) {
- LOG4CXX_WARN_WITH_ERRNO(logger_, "Failed to shutdown byesocket");
- }
+
+ char dummy[1] = {0};
+ int ret = write(pipe_fds_[1], dummy, sizeof(dummy));
+ if (ret <= 0) {
+ LOG4CXX_WARN_WITH_ERRNO(
+ logger_, "Failed to send stop message to TCP server socket loop");
}
- close(byesocket);
}
TransportAdapter::Error TcpClientListener::StartListening() {
LOG4CXX_AUTO_TRACE(logger_);
- if (thread_->is_running()) {
+ if (started_) {
LOG4CXX_WARN(
logger_,
"TransportAdapter::BAD_STATE. Listener has already been started");
return TransportAdapter::BAD_STATE;
}
- if (!thread_->start()) {
- LOG4CXX_ERROR(logger_, "Tcp client listener thread start failed");
+ if (!interface_listener_->Start()) {
return TransportAdapter::FAIL;
}
+
+ if (!IsListeningOnSpecificInterface()) {
+ TransportAdapter::Error ret = StartListeningThread();
+ if (TransportAdapter::OK != ret) {
+ LOG4CXX_ERROR(logger_, "Tcp client listener thread start failed");
+ interface_listener_->Stop();
+ return ret;
+ }
+ }
+
+ started_ = true;
LOG4CXX_INFO(logger_, "Tcp client listener has started successfully");
return TransportAdapter::OK;
}
@@ -319,16 +388,286 @@ TcpClientListener::ListeningThreadDelegate::ListeningThreadDelegate(
TransportAdapter::Error TcpClientListener::StopListening() {
LOG4CXX_AUTO_TRACE(logger_);
- if (!thread_->is_running()) {
+ if (!started_) {
LOG4CXX_DEBUG(logger_, "TcpClientListener is not running now");
return TransportAdapter::BAD_STATE;
}
- thread_->join();
+ interface_listener_->Stop();
+
+ StopListeningThread();
+ started_ = false;
LOG4CXX_INFO(logger_, "Tcp client listener has stopped successfully");
return TransportAdapter::OK;
}
+TransportAdapter::Error TcpClientListener::StartListeningThread() {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ // StartListening() can be called from multiple threads
+ sync_primitives::AutoLock auto_lock(start_stop_lock_);
+
+ if (pipe_fds_[0] < 0 || pipe_fds_[1] < 0) {
+ // recreate the pipe every time, so that the thread loop will not get
+ // leftover
+ // data inside pipe after it is started
+ if (pipe(pipe_fds_) != 0) {
+ LOG4CXX_ERROR_WITH_ERRNO(logger_, "Failed to create internal pipe");
+ return TransportAdapter::FAIL;
+ }
+ if (!SetNonblocking(pipe_fds_[0])) {
+ LOG4CXX_WARN(logger_, "Failed to configure pipe to non-blocking");
+ }
+ }
+
+ thread_stop_requested_ = false;
+
+ if (!thread_->start()) {
+ return TransportAdapter::FAIL;
+ }
+ return TransportAdapter::OK;
+}
+
+TransportAdapter::Error TcpClientListener::StopListeningThread() {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ // StopListening() can be called from multiple threads
+ sync_primitives::AutoLock auto_lock(start_stop_lock_);
+
+ thread_->join();
+
+ close(pipe_fds_[1]);
+ pipe_fds_[1] = -1;
+ close(pipe_fds_[0]);
+ pipe_fds_[0] = -1;
+
+ return TransportAdapter::OK;
+}
+
+void TcpClientListener::OnIPAddressUpdated(const std::string ipv4_addr,
+ const std::string ipv6_addr) {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ // Since we only create a TCP socket with IPv4 option (AF_INET), currently we
+ // do not use IPv6 address.
+ if (ipv4_addr != current_ip_address_) {
+ if (IsListeningOnSpecificInterface()) {
+ if (!current_ip_address_.empty()) {
+ // the server socket is running, terminate it
+ LOG4CXX_DEBUG(logger_,
+ "Stopping current TCP server socket on "
+ << designated_interface_);
+ StopOnNetworkInterface();
+ }
+ if (!ipv4_addr.empty()) {
+ // start (or restart) server socket with the new IP address
+ LOG4CXX_DEBUG(
+ logger_, "Starting TCP server socket on " << designated_interface_);
+ StartOnNetworkInterface();
+ }
+ }
+
+ current_ip_address_ = ipv4_addr;
+
+ std::string enabled = !current_ip_address_.empty() ? "true" : "false";
+ std::ostringstream oss;
+ oss << port_;
+
+ TransportConfig config;
+ config.insert(std::make_pair(tc_enabled, enabled));
+ config.insert(std::make_pair(tc_tcp_ip_address, current_ip_address_));
+ config.insert(std::make_pair(tc_tcp_port, oss.str()));
+
+ controller_->TransportConfigUpdated(config);
+ }
+}
+
+bool TcpClientListener::StartOnNetworkInterface() {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ // this method is only for the case that network interface is specified
+ if (IsListeningOnSpecificInterface()) {
+ {
+ // make sure that two threads will not update socket_ at the same time
+ sync_primitives::AutoLock auto_lock(start_stop_lock_);
+ if (socket_ < 0) {
+ socket_ = CreateIPv4ServerSocket(port_, designated_interface_);
+ if (-1 == socket_) {
+ LOG4CXX_WARN(logger_, "Failed to create TCP socket");
+ return false;
+ }
+ }
+ }
+
+ if (TransportAdapter::OK != StartListeningThread()) {
+ LOG4CXX_WARN(logger_, "Failed to start TCP client listener");
+ return false;
+ }
+ LOG4CXX_INFO(logger_,
+ "TCP server socket started on " << designated_interface_);
+ }
+ return true;
+}
+
+bool TcpClientListener::StopOnNetworkInterface() {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ if (IsListeningOnSpecificInterface()) {
+ if (TransportAdapter::OK != StopListeningThread()) {
+ LOG4CXX_WARN(logger_, "Failed to stop TCP client listener");
+ return false;
+ }
+
+ {
+ sync_primitives::AutoLock auto_lock(start_stop_lock_);
+ DestroyServerSocket(socket_);
+ socket_ = -1;
+ }
+
+ LOG4CXX_INFO(logger_,
+ "TCP server socket on " << designated_interface_
+ << " stopped");
+ }
+ return true;
+}
+
+bool TcpClientListener::IsListeningOnSpecificInterface() const {
+ return !designated_interface_.empty();
+}
+
+int TcpClientListener::CreateIPv4ServerSocket(
+ uint16_t port, const std::string interface_name) {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ struct in_addr ipv4_address;
+ memset(&ipv4_address, 0, sizeof(ipv4_address));
+ if (interface_name.empty()) {
+ ipv4_address.s_addr = htonl(INADDR_ANY);
+ } else if (!GetIPv4Address(interface_name, &ipv4_address)) {
+ return -1;
+ }
+
+ int sock = socket(AF_INET, SOCK_STREAM, 0);
+ if (-1 == sock) {
+ LOG4CXX_ERROR_WITH_ERRNO(logger_, "Failed to create socket");
+ return -1;
+ }
+
+ sockaddr_in server_address = {0};
+ server_address.sin_family = AF_INET;
+ server_address.sin_port = htons(port);
+ server_address.sin_addr = ipv4_address;
+
+ int optval = 1;
+ if (0 !=
+ setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval))) {
+ LOG4CXX_WARN_WITH_ERRNO(logger_, "setsockopt SO_REUSEADDR failed");
+ }
+
+ if (bind(sock,
+ reinterpret_cast<sockaddr*>(&server_address),
+ sizeof(server_address)) != 0) {
+ LOG4CXX_ERROR_WITH_ERRNO(logger_, "bind() failed");
+ close(sock);
+ return -1;
+ }
+
+ const int kBacklog = 128;
+ if (0 != listen(sock, kBacklog)) {
+ LOG4CXX_ERROR_WITH_ERRNO(logger_, "listen() failed");
+ close(sock);
+ return -1;
+ }
+
+ return sock;
+}
+
+void TcpClientListener::DestroyServerSocket(int sock) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ if (sock >= 0) {
+ if (shutdown(sock, SHUT_RDWR) != 0) {
+ LOG4CXX_ERROR_WITH_ERRNO(logger_, "Failed to shutdown socket");
+ }
+ if (close(sock) != 0) {
+ LOG4CXX_ERROR_WITH_ERRNO(logger_, "Failed to close socket");
+ }
+ }
+}
+
+bool TcpClientListener::GetIPv4Address(const std::string interface_name,
+ struct in_addr* ip_address) {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+#ifdef BUILD_TESTS
+ if (testing_) {
+ // don't actually call getifaddrs(), instead return a dummy address of
+ // INADDR_LOOPBACK
+ struct in_addr dummy_addr;
+ dummy_addr.s_addr = htonl(INADDR_LOOPBACK);
+
+ if (ip_address != NULL) {
+ *ip_address = dummy_addr;
+ }
+ return true;
+ }
+#endif // BUILD_TESTS
+
+ struct ifaddrs* if_list;
+ if (getifaddrs(&if_list) != 0) {
+ LOG4CXX_WARN(logger_, "getifaddrs failed");
+ return false;
+ }
+
+ struct ifaddrs* interface;
+ bool found = false;
+
+ for (interface = if_list; interface != NULL;
+ interface = interface->ifa_next) {
+ if (interface->ifa_name == NULL) {
+ continue;
+ }
+ if (interface_name == interface->ifa_name) {
+ if (interface->ifa_addr == NULL) {
+ continue;
+ }
+ switch (interface->ifa_addr->sa_family) {
+ case AF_INET: {
+ struct sockaddr_in* addr =
+ reinterpret_cast<struct sockaddr_in*>(interface->ifa_addr);
+ if (ip_address != NULL) {
+ *ip_address = addr->sin_addr;
+ }
+ found = true;
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ }
+
+ freeifaddrs(if_list);
+
+ return found;
+}
+
+static bool SetNonblocking(int s) {
+ int prev_flag = fcntl(s, F_GETFL, 0);
+ if (prev_flag == -1) {
+ LOG4CXX_ERROR_WITH_ERRNO(logger_, "Failed to acquire socket flag");
+ return false;
+ }
+
+ int ret = fcntl(s, F_SETFL, prev_flag | O_NONBLOCK);
+ if (ret == -1) {
+ LOG4CXX_ERROR_WITH_ERRNO(logger_,
+ "Failed to configure socket to non-blocking");
+ return false;
+ }
+
+ return true;
+}
+
} // namespace transport_adapter
} // namespace transport_manager
diff --git a/src/components/transport_manager/src/tcp/tcp_connection_factory.cc b/src/components/transport_manager/src/tcp/tcp_connection_factory.cc
index 114425076a..e202554f8f 100644
--- a/src/components/transport_manager/src/tcp/tcp_connection_factory.cc
+++ b/src/components/transport_manager/src/tcp/tcp_connection_factory.cc
@@ -35,7 +35,6 @@
#include "transport_manager/tcp/tcp_server_originated_socket_connection.h"
#include "utils/logger.h"
-#include "utils/make_shared.h"
namespace transport_manager {
namespace transport_adapter {
@@ -56,8 +55,8 @@ TransportAdapter::Error TcpConnectionFactory::CreateConnection(
LOG4CXX_DEBUG(logger_,
"DeviceUID: " << &device_uid
<< ", ApplicationHandle: " << &app_handle);
- utils::SharedPtr<TcpServerOriginatedSocketConnection> connection =
- utils::MakeShared<TcpServerOriginatedSocketConnection>(
+ std::shared_ptr<TcpServerOriginatedSocketConnection> connection =
+ std::make_shared<TcpServerOriginatedSocketConnection>(
device_uid, app_handle, controller_);
controller_->ConnectionCreated(connection, device_uid, app_handle);
const TransportAdapter::Error error = connection->Start();
diff --git a/src/components/transport_manager/src/tcp/tcp_server_originated_socket_connection.cc b/src/components/transport_manager/src/tcp/tcp_server_originated_socket_connection.cc
index 516f2d3ec4..2f10bd9454 100644
--- a/src/components/transport_manager/src/tcp/tcp_server_originated_socket_connection.cc
+++ b/src/components/transport_manager/src/tcp/tcp_server_originated_socket_connection.cc
@@ -56,7 +56,7 @@ bool TcpServerOriginatedSocketConnection::Establish(ConnectError** error) {
DCHECK(error);
LOG4CXX_DEBUG(logger_, "error " << error);
DeviceSptr device = controller()->FindDevice(device_handle());
- if (!device.valid()) {
+ if (device.use_count() == 0) {
LOG4CXX_ERROR(logger_, "Device " << device_handle() << " not found");
*error = new ConnectError();
return false;
diff --git a/src/components/transport_manager/src/tcp/tcp_transport_adapter.cc b/src/components/transport_manager/src/tcp/tcp_transport_adapter.cc
index 0e9e63263b..b3dbf49628 100644
--- a/src/components/transport_manager/src/tcp/tcp_transport_adapter.cc
+++ b/src/components/transport_manager/src/tcp/tcp_transport_adapter.cc
@@ -55,14 +55,35 @@ TcpTransportAdapter::TcpTransportAdapter(
const uint16_t port,
resumption::LastState& last_state,
const TransportManagerSettings& settings)
- : TransportAdapterImpl(NULL,
- new TcpConnectionFactory(this),
- new TcpClientListener(this, port, true),
- last_state,
- settings) {}
+ : TransportAdapterImpl(
+ NULL,
+ new TcpConnectionFactory(this),
+ new TcpClientListener(
+ this,
+ port,
+ true,
+ settings.transport_manager_tcp_adapter_network_interface()),
+ last_state,
+ settings) {}
TcpTransportAdapter::~TcpTransportAdapter() {}
+void TcpTransportAdapter::TransportConfigUpdated(
+ const TransportConfig& new_config) {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ transport_config_ = new_config;
+
+ // call the method of parent class to trigger OnTransportConfigUpdated() for
+ // the listeners
+ TransportAdapterImpl::TransportConfigUpdated(new_config);
+}
+
+TransportConfig TcpTransportAdapter::GetTransportConfiguration() const {
+ LOG4CXX_AUTO_TRACE(logger_);
+ return transport_config_;
+}
+
DeviceType TcpTransportAdapter::GetDeviceType() const {
return TCP;
}
@@ -79,8 +100,8 @@ void TcpTransportAdapter::Store() const {
if (!device) { // device could have been disconnected
continue;
}
- utils::SharedPtr<TcpDevice> tcp_device =
- DeviceSptr::static_pointer_cast<TcpDevice>(device);
+ std::shared_ptr<TcpDevice> tcp_device =
+ std::static_pointer_cast<TcpDevice>(device);
Json::Value device_dictionary;
device_dictionary["name"] = tcp_device->name();
struct in_addr address;
diff --git a/src/components/transport_manager/src/transport_adapter/transport_adapter_impl.cc b/src/components/transport_manager/src/transport_adapter/transport_adapter_impl.cc
index bdacd68006..346139cbd2 100644
--- a/src/components/transport_manager/src/transport_adapter/transport_adapter_impl.cc
+++ b/src/components/transport_manager/src/transport_adapter/transport_adapter_impl.cc
@@ -43,18 +43,24 @@
namespace transport_manager {
namespace transport_adapter {
+const char* tc_enabled = "enabled";
+const char* tc_tcp_port = "tcp_port";
+const char* tc_tcp_ip_address = "tcp_ip_address";
+
CREATE_LOGGERPTR_GLOBAL(logger_, "TransportManager")
namespace {
-// @deprecated DeviceTypes: PASA_AOA, PASA_BLUETOOTH, MME
DeviceTypes devicesType = {
std::make_pair(DeviceType::AOA, std::string("USB_AOA")),
- std::make_pair(DeviceType::PASA_AOA, std::string("USB_AOA")),
std::make_pair(DeviceType::BLUETOOTH, std::string("BLUETOOTH")),
- std::make_pair(DeviceType::PASA_BLUETOOTH, std::string("BLUETOOTH")),
- std::make_pair(DeviceType::MME, std::string("USB_IOS")),
std::make_pair(DeviceType::IOS_BT, std::string("BLUETOOTH_IOS")),
std::make_pair(DeviceType::IOS_USB, std::string("USB_IOS")),
- std::make_pair(DeviceType::TCP, std::string("WIFI"))};
+ std::make_pair(DeviceType::TCP, std::string("WIFI")),
+ std::make_pair(DeviceType::IOS_USB_HOST_MODE,
+ std::string("USB_IOS_HOST_MODE")),
+ std::make_pair(DeviceType::IOS_USB_DEVICE_MODE,
+ std::string("USB_IOS_DEVICE_MODE")),
+ std::make_pair(DeviceType::IOS_CARPLAY_WIRELESS,
+ std::string("CARPLAY_WIRELESS_IOS"))};
}
TransportAdapterImpl::TransportAdapterImpl(
@@ -695,6 +701,16 @@ void TransportAdapterImpl::DataSendFailed(
LOG4CXX_TRACE(logger_, "exit");
}
+void TransportAdapterImpl::TransportConfigUpdated(
+ const TransportConfig& new_config) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ for (TransportAdapterListenerList::iterator it = listeners_.begin();
+ it != listeners_.end();
+ ++it) {
+ (*it)->OnTransportConfigUpdated(this);
+ }
+}
+
void TransportAdapterImpl::DoTransportSwitch() const {
LOG4CXX_AUTO_TRACE(logger_);
std::for_each(
@@ -803,16 +819,16 @@ ApplicationList TransportAdapterImpl::GetApplicationList(
const DeviceUID& device_id) const {
LOG4CXX_TRACE(logger_, "enter. device_id: " << &device_id);
DeviceSptr device = FindDevice(device_id);
- if (device.valid()) {
+ if (device.use_count() != 0) {
ApplicationList lst = device->GetApplicationList();
LOG4CXX_TRACE(logger_,
"exit with ApplicationList. It's size = "
- << lst.size() << " Condition: device.valid()");
+ << lst.size() << " Condition: device.use_count() != 0");
return lst;
}
- LOG4CXX_TRACE(
- logger_,
- "exit with empty ApplicationList. Condition: NOT device.valid()");
+ LOG4CXX_TRACE(logger_,
+ "exit with empty ApplicationList. Condition: NOT "
+ "device.use_count() != 0");
return ApplicationList();
}
@@ -875,7 +891,7 @@ bool TransportAdapterImpl::IsInitialised() const {
std::string TransportAdapterImpl::DeviceName(const DeviceUID& device_id) const {
DeviceSptr device = FindDevice(device_id);
- if (device.valid()) {
+ if (device.use_count() != 0) {
return device->name();
} else {
return "";
diff --git a/src/components/transport_manager/src/transport_adapter/transport_adapter_listener_impl.cc b/src/components/transport_manager/src/transport_adapter/transport_adapter_listener_impl.cc
index f1181ce921..544cdde999 100644
--- a/src/components/transport_manager/src/transport_adapter/transport_adapter_listener_impl.cc
+++ b/src/components/transport_manager/src/transport_adapter/transport_adapter_listener_impl.cc
@@ -275,7 +275,7 @@ void TransportAdapterListenerImpl::OnDataSendDone(
device,
app_id,
data_container,
- new BaseError());
+ std::make_shared<BaseError>());
if (transport_manager_ != NULL &&
transport_manager::E_SUCCESS !=
transport_manager_->ReceiveEventFromDevice(event)) {
@@ -376,4 +376,23 @@ void TransportAdapterListenerImpl::OnTransportSwitchRequested(
LOG4CXX_WARN(logger_, "Failed to receive event from device");
}
}
+
+void TransportAdapterListenerImpl::OnTransportConfigUpdated(
+ const transport_adapter::TransportAdapter* adapter) {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ const TransportAdapterEvent event(EventTypeEnum::ON_TRANSPORT_CONFIG_UPDATED,
+ transport_adapter_,
+ "",
+ 0,
+ ::protocol_handler::RawMessagePtr(),
+ BaseErrorPtr());
+
+ if (transport_manager_ != NULL &&
+ transport_manager::E_SUCCESS !=
+ transport_manager_->ReceiveEventFromDevice(event)) {
+ LOG4CXX_WARN(logger_, "Failed to receive event from device");
+ }
+}
+
} // namespace transport_manager
diff --git a/src/components/transport_manager/src/transport_manager_impl.cc b/src/components/transport_manager/src/transport_manager_impl.cc
index a364220a64..2b0296debb 100644
--- a/src/components/transport_manager/src/transport_manager_impl.cc
+++ b/src/components/transport_manager/src/transport_manager_impl.cc
@@ -44,7 +44,7 @@
#include "utils/macro.h"
#include "utils/logger.h"
-#include "utils/make_shared.h"
+
#include "utils/timer_task_impl.h"
#include "transport_manager/common.h"
#include "transport_manager/transport_manager_listener.h"
@@ -529,6 +529,8 @@ int TransportManagerImpl::Reinit() {
LOG4CXX_AUTO_TRACE(logger_);
DisconnectAllDevices();
TerminateAllAdapters();
+ device_to_adapter_map_.clear();
+ connection_id_counter_ = 0;
int ret = InitAllAdapters();
return ret;
}
@@ -1066,7 +1068,7 @@ void TransportManagerImpl::Handle(TransportAdapterEvent event) {
LOG4CXX_ERROR(logger_, "Transport adapter failed to send data");
// TODO(YK): potential error case -> thread unsafe
// update of message content
- if (event.event_data.valid()) {
+ if (event.event_data.use_count() != 0) {
event.event_data->set_waiting(true);
} else {
LOG4CXX_DEBUG(logger_, "Data is invalid");
@@ -1144,6 +1146,13 @@ void TransportManagerImpl::Handle(TransportAdapterEvent event) {
LOG4CXX_DEBUG(logger_, "eevent_type = ON_UNEXPECTED_DISCONNECT");
break;
}
+ case EventTypeEnum::ON_TRANSPORT_CONFIG_UPDATED: {
+ LOG4CXX_DEBUG(logger_, "event_type = ON_TRANSPORT_CONFIG_UPDATED");
+ transport_adapter::TransportConfig config =
+ event.transport_adapter->GetTransportConfiguration();
+ RaiseEvent(&TransportManagerListener::OnTransportConfigUpdated, config);
+ break;
+ }
} // switch
LOG4CXX_TRACE(logger_, "exit");
}
@@ -1203,9 +1212,9 @@ TransportManagerImpl::ConnectionInternal::ConnectionInternal(
const DeviceHandle device_handle)
: transport_manager(transport_manager)
, transport_adapter(transport_adapter)
- , timer(utils::MakeShared<timer::Timer,
- const char*,
- ::timer::TimerTaskImpl<ConnectionInternal>*>(
+ , timer(std::make_shared<timer::Timer,
+ const char*,
+ ::timer::TimerTaskImpl<ConnectionInternal>*>(
"TM DiscRoutine",
new ::timer::TimerTaskImpl<ConnectionInternal>(
this, &ConnectionInternal::DisconnectFailedRoutine)))
diff --git a/src/components/transport_manager/src/usb/libusb/usb_connection.cc b/src/components/transport_manager/src/usb/libusb/usb_connection.cc
index e9ab2bae8e..212e6e0ec3 100644
--- a/src/components/transport_manager/src/usb/libusb/usb_connection.cc
+++ b/src/components/transport_manager/src/usb/libusb/usb_connection.cc
@@ -224,7 +224,7 @@ void UsbConnection::OnOutTransfer(libusb_transfer* transfer) {
device_uid_, app_handle_, current_out_message_, DataSendError());
PopOutMessage();
}
- if (!current_out_message_.valid()) {
+ if (current_out_message_.use_count() == 0) {
libusb_free_transfer(transfer);
out_transfer_ = NULL;
waiting_out_transfer_cancel_ = false;
@@ -242,7 +242,7 @@ TransportAdapter::Error UsbConnection::SendData(
return TransportAdapter::BAD_STATE;
}
sync_primitives::AutoLock locker(out_messages_mutex_);
- if (current_out_message_.valid()) {
+ if (current_out_message_.use_count() != 0) {
out_messages_.push_back(message);
} else {
current_out_message_ = message;
diff --git a/src/components/transport_manager/src/usb/qnx/usb_connection.cc b/src/components/transport_manager/src/usb/qnx/usb_connection.cc
index 516a367ebc..b9386c5d9f 100644
--- a/src/components/transport_manager/src/usb/qnx/usb_connection.cc
+++ b/src/components/transport_manager/src/usb/qnx/usb_connection.cc
@@ -230,7 +230,7 @@ void UsbConnection::OnOutTransfer(usbd_urb* urb) {
}
}
- if ((!disconnecting_) && current_out_message_.valid()) {
+ if ((!disconnecting_) && (current_out_message_.use_count() != 0)) {
PostOutTransfer();
} else {
pending_out_transfer_ = false;
@@ -243,7 +243,7 @@ TransportAdapter::Error UsbConnection::SendData(
return TransportAdapter::BAD_STATE;
}
sync_primitives::AutoLock locker(out_messages_mutex_);
- if (current_out_message_.valid()) {
+ if (current_out_message_.use_count() != 0) {
out_messages_.push_back(message);
} else {
current_out_message_ = message;
diff --git a/src/components/transport_manager/src/usb/usb_connection_factory.cc b/src/components/transport_manager/src/usb/usb_connection_factory.cc
index 1136dfad21..528855cd50 100644
--- a/src/components/transport_manager/src/usb/usb_connection_factory.cc
+++ b/src/components/transport_manager/src/usb/usb_connection_factory.cc
@@ -34,7 +34,6 @@
#include "transport_manager/usb/usb_device.h"
#include "transport_manager/transport_adapter/transport_adapter_impl.h"
#include "utils/logger.h"
-#include "utils/make_shared.h"
#if defined(__QNXNTO__)
#include "transport_manager/usb/qnx/usb_connection.h"
@@ -65,21 +64,21 @@ TransportAdapter::Error UsbConnectionFactory::CreateConnection(
"enter DeviceUID: " << &device_uid
<< ", ApplicationHandle: " << &app_handle);
DeviceSptr device = controller_->FindDevice(device_uid);
- if (!device.valid()) {
+ if (device.use_count() == 0) {
LOG4CXX_ERROR(logger_, "device " << device_uid << " not found");
- LOG4CXX_TRACE(
- logger_,
- "exit with TransportAdapter::BAD_PARAM. Condition: !device.valid()");
+ LOG4CXX_TRACE(logger_,
+ "exit with TransportAdapter::BAD_PARAM. Condition: "
+ "device.use_count() == 0");
return TransportAdapter::BAD_PARAM;
}
UsbDevice* usb_device = static_cast<UsbDevice*>(device.get());
- utils::SharedPtr<UsbConnection> connection =
- utils::MakeShared<UsbConnection>(device_uid,
- app_handle,
- controller_,
- usb_handler_,
- usb_device->usb_device());
+ std::shared_ptr<UsbConnection> connection =
+ std::make_shared<UsbConnection>(device_uid,
+ app_handle,
+ controller_,
+ usb_handler_,
+ usb_device->usb_device());
controller_->ConnectionCreated(connection, device_uid, app_handle);
if (connection->Init()) {
LOG4CXX_INFO(logger_, "USB connection initialised");