summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/components/transport_manager/include/transport_manager/iap2_emulation/iap2_transport_adapter.h44
-rw-r--r--src/components/transport_manager/include/transport_manager/tcp/tcp_device.h12
-rw-r--r--src/components/transport_manager/src/iap2_emulation/iap2_transport_adapter.cc86
-rw-r--r--src/components/transport_manager/src/tcp/tcp_client_listener.cc9
-rw-r--r--src/components/transport_manager/src/tcp/tcp_device.cc17
5 files changed, 165 insertions, 3 deletions
diff --git a/src/components/transport_manager/include/transport_manager/iap2_emulation/iap2_transport_adapter.h b/src/components/transport_manager/include/transport_manager/iap2_emulation/iap2_transport_adapter.h
index de8a3c0080..df8aa3a76f 100644
--- a/src/components/transport_manager/include/transport_manager/iap2_emulation/iap2_transport_adapter.h
+++ b/src/components/transport_manager/include/transport_manager/iap2_emulation/iap2_transport_adapter.h
@@ -36,6 +36,11 @@
#include "transport_manager/transport_manager_settings.h"
#include "resumption/last_state.h"
#include "utils/macro.h"
+#include "utils/threads/thread_delegate.h"
+
+namespace threads {
+class Thread;
+}
namespace transport_manager {
namespace transport_adapter {
@@ -93,8 +98,13 @@ class IAP2USBEmulationTransportAdapter : public TcpTransportAdapter {
const TransportManagerSettings& settings);
/**
+ * Destructor
+ */
+ ~IAP2USBEmulationTransportAdapter();
+
+ /**
* @brief DeviceSwitched is called during switching from iAP2 Bluetooth to
- * iAP2 USB transport
+ * iAP2 USB transport. Sends ACK signal for switching request.
* @param device_handle Device handle of switched device
*/
void DeviceSwitched(const DeviceUID& device_handle) OVERRIDE;
@@ -105,6 +115,38 @@ class IAP2USBEmulationTransportAdapter : public TcpTransportAdapter {
* @return Device type
*/
DeviceType GetDeviceType() const OVERRIDE;
+
+ private:
+ /**
+ * @brief The IAPSignalHandlerDelegate class handles signals from the system
+ * to start transport switching flow
+ */
+ class IAPSignalHandlerDelegate : public threads::ThreadDelegate {
+ public:
+ /**
+ * @brief IAPSignalHandlerDelegate Constructor
+ * @param adapter Pointer to iAP2 USB adapter
+ */
+ IAPSignalHandlerDelegate(IAP2USBEmulationTransportAdapter* adapter);
+
+ /**
+ * @brief threadMain Main loop to track incoming signals
+ */
+ void threadMain() OVERRIDE;
+
+ /**
+ * @brief exitThreadMain Stops main loop
+ */
+ void exitThreadMain() OVERRIDE;
+
+ private:
+ IAP2USBEmulationTransportAdapter* adapter_;
+ bool run_flag_;
+ int in_;
+ };
+
+ threads::Thread* signal_handler_;
+ int out_;
};
}
} // namespace transport_manager::transport_adapter
diff --git a/src/components/transport_manager/include/transport_manager/tcp/tcp_device.h b/src/components/transport_manager/include/transport_manager/tcp/tcp_device.h
index 981ba9f6ee..6eb15b638e 100644
--- a/src/components/transport_manager/include/transport_manager/tcp/tcp_device.h
+++ b/src/components/transport_manager/include/transport_manager/tcp/tcp_device.h
@@ -66,6 +66,18 @@ class TcpDevice : public Device {
**/
TcpDevice(const in_addr_t& in_addr, const std::string& name);
+ #if defined (BUILD_TESTS)
+ /**
+ * @brief TcpDevice
+ * @param in_addr IP address of device
+ * @param device_uid Unique device id
+ * @param transport_switch_id Id used for transport switching
+ */
+ TcpDevice(const in_addr_t& in_addr,
+ const std::string& device_uid,
+ const std::string& transport_switch_id);
+#endif
+
virtual ~TcpDevice();
/**
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 20dc059385..1429a57e9e 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
@@ -32,6 +32,21 @@
#include "transport_manager/iap2_emulation/iap2_transport_adapter.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdio.h>
+
+#include "utils/threads/thread.h"
+#include "utils/file_system.h"
+
+namespace {
+mode_t mode = 0666;
+const auto in_signals_channel = "iap_signals_in";
+const auto out_signals_channel = "iap_signals_out";
+} // namespace
+
namespace transport_manager {
namespace transport_adapter {
@@ -58,17 +73,86 @@ IAP2USBEmulationTransportAdapter::IAP2USBEmulationTransportAdapter(
const uint16_t port,
resumption::LastState& last_state,
const TransportManagerSettings& settings)
- : TcpTransportAdapter(port, last_state, settings) {}
+ : TcpTransportAdapter(port, last_state, settings), out_(0) {
+ auto delegate = new IAPSignalHandlerDelegate(this);
+ signal_handler_ =
+ threads::CreateThread("iAP signal handler", delegate);
+ signal_handler_->start();
+ LOG4CXX_DEBUG(logger_, "Out signals channel creation result: "
+ << mkfifo(out_signals_channel, mode));
+}
+
+IAP2USBEmulationTransportAdapter::~IAP2USBEmulationTransportAdapter() {
+ signal_handler_->join();
+ threads::DeleteThread(signal_handler_);
+ LOG4CXX_DEBUG(logger_, "Out close result: " << close(out_));
+ LOG4CXX_DEBUG(logger_, "Out unlink result: " << unlink(out_signals_channel));
+}
void IAP2USBEmulationTransportAdapter::DeviceSwitched(
const DeviceUID& device_handle) {
LOG4CXX_AUTO_TRACE(logger_);
UNUSED(device_handle);
+ const auto switch_signal_ack = std::string("SDL_TRANSPORT_SWITCH_ACK\n");
+
+ auto out_ = open(out_signals_channel, O_WRONLY);
+ LOG4CXX_DEBUG(logger_, "Out channel descriptor: " << out_);
+
+ const auto bytes =
+ write(out_, switch_signal_ack.c_str(), switch_signal_ack.size());
+ LOG4CXX_DEBUG(logger_, "Written bytes to out: " << bytes);
+
+ LOG4CXX_DEBUG(logger_, "Switching signal ACK is sent");
LOG4CXX_DEBUG(logger_, "iAP2 USB device is switched with iAP2 Bluetooth");
}
DeviceType IAP2USBEmulationTransportAdapter::GetDeviceType() const {
return IOS_USB;
}
+
+IAP2USBEmulationTransportAdapter::
+IAPSignalHandlerDelegate::IAPSignalHandlerDelegate(
+ IAP2USBEmulationTransportAdapter* adapter)
+ : adapter_(adapter),
+ run_flag_(true),
+ in_(0) {
+ LOG4CXX_DEBUG(logger_, "In signals channel creation result: "
+ << mkfifo(in_signals_channel, mode));
+}
+
+void IAP2USBEmulationTransportAdapter::IAPSignalHandlerDelegate::threadMain() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ LOG4CXX_DEBUG(logger_, "Signal handling is started");
+ const auto switch_signal = "SDL_TRANSPORT_SWITCH";
+ LOG4CXX_DEBUG(logger_, "Waiting for signal: " << switch_signal);
+
+ in_ = open(in_signals_channel, O_RDONLY);
+ LOG4CXX_DEBUG(logger_, "In channel descriptor: " << in_);
+
+ const auto size = 32;
+ while (run_flag_) {
+ char buffer[size];
+ auto bytes = read(in_, &buffer, size);
+ if (!bytes) {
+ continue;
+ }
+ LOG4CXX_DEBUG(logger_, "Read in bytes: " << bytes);
+ std::string str(buffer);
+ if (std::string::npos != str.find(switch_signal)) {
+ LOG4CXX_DEBUG(logger_, "Switch signal received.");
+ adapter_->DoTransportSwitch();
+ }
+ }
+}
+
+void IAP2USBEmulationTransportAdapter::
+IAPSignalHandlerDelegate::exitThreadMain() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ LOG4CXX_DEBUG(logger_, "Stopping signal handling.");
+ run_flag_ = false;
+ LOG4CXX_DEBUG(logger_, "In close result: " << close(in_));
+ LOG4CXX_DEBUG(logger_, "In unlink result: " << unlink(in_signals_channel));
+}
+
}
} // namespace transport_manager::transport_adapter
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 bce15e4e07..839eed9a5b 100644
--- a/src/components/transport_manager/src/tcp/tcp_client_listener.cc
+++ b/src/components/transport_manager/src/tcp/tcp_client_listener.cc
@@ -235,9 +235,16 @@ void TcpClientListener::Loop() {
if (enable_keepalive_) {
SetKeepaliveOptions(connection_fd);
}
-
+#if defined (BUILD_TESTS)
+ const auto device_uid = device_name +
+ std::string(":") +
+ std::to_string(port_);
+ TcpDevice* tcp_device =
+ new TcpDevice(client_address.sin_addr.s_addr, device_uid, device_name);
+#else
TcpDevice* tcp_device =
new TcpDevice(client_address.sin_addr.s_addr, device_name);
+#endif // BUILD_TESTS
DeviceSptr device = controller_->AddDevice(tcp_device);
tcp_device = static_cast<TcpDevice*>(device.get());
const ApplicationHandle app_handle =
diff --git a/src/components/transport_manager/src/tcp/tcp_device.cc b/src/components/transport_manager/src/tcp/tcp_device.cc
index d3f132759a..1a0ca80d94 100644
--- a/src/components/transport_manager/src/tcp/tcp_device.cc
+++ b/src/components/transport_manager/src/tcp/tcp_device.cc
@@ -46,6 +46,23 @@ TcpDevice::TcpDevice(const in_addr_t& in_addr, const std::string& name)
LOG4CXX_AUTO_TRACE(logger_);
}
+#if defined (BUILD_TESTS)
+TcpDevice::TcpDevice(const in_addr_t& in_addr,
+ const std::string& device_uid,
+ const std::string& transport_switch_id)
+ : Device(device_uid, device_uid, transport_switch_id),
+ applications_mutex_(),
+ in_addr_(in_addr),
+ last_handle_(0) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ LOG4CXX_DEBUG(logger_,
+ "Device created with transport switch emulation support.");
+ LOG4CXX_DEBUG(logger_,
+ "Device parameters: " << device_uid
+ << " / " << transport_switch_id);
+}
+#endif // BUILD_TESTS
+
bool TcpDevice::IsSameAs(const Device* other) const {
LOG4CXX_AUTO_TRACE(logger_);
LOG4CXX_DEBUG(logger_, "Device: " << other);