summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrey Oleynik (GitHub) <aoleynik@luxoft.com>2017-12-05 12:47:10 +0200
committerAndriy Byzhynar <AByzhynar@luxoft.com>2018-01-18 12:03:51 +0200
commit176a30ed49f29f88e1497bcb3ce9a0973164f2ae (patch)
tree5ecc547ce645c2dd246e913fd7e6b0a72f75816e
parent8e628176a3cfe6d9bc47c80ba8c2a44cc0d961f0 (diff)
downloadsdl_core-176a30ed49f29f88e1497bcb3ce9a0973164f2ae.tar.gz
Changes implementation of iAP2 transport adapter emulation
New implementation considers external switching flow triggering so no implementation includes separate thread which manages incoming signals and starts the flow. Also ACK is being sent back to the system.
-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);