summaryrefslogtreecommitdiff
path: root/src/components/transport_manager/src/iap2_emulation/iap2_transport_adapter.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/transport_manager/src/iap2_emulation/iap2_transport_adapter.cc')
-rw-r--r--src/components/transport_manager/src/iap2_emulation/iap2_transport_adapter.cc174
1 files changed, 174 insertions, 0 deletions
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
new file mode 100644
index 0000000000..6b7d44ea8d
--- /dev/null
+++ b/src/components/transport_manager/src/iap2_emulation/iap2_transport_adapter.cc
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) 2017, Ford Motor Company
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#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 {
+static const mode_t mode = 0666;
+static const auto in_signals_channel = "iap_signals_in";
+static const auto out_signals_channel = "iap_signals_out";
+} // namespace
+
+namespace transport_manager {
+namespace transport_adapter {
+
+CREATE_LOGGERPTR_GLOBAL(logger_, "IAP2Emulation");
+
+IAP2BluetoothEmulationTransportAdapter::IAP2BluetoothEmulationTransportAdapter(
+ const uint16_t port,
+ resumption::LastState& last_state,
+ const TransportManagerSettings& settings)
+ : TcpTransportAdapter(port, last_state, settings) {}
+
+void IAP2BluetoothEmulationTransportAdapter::DeviceSwitched(
+ const DeviceUID& device_handle) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ UNUSED(device_handle);
+ DCHECK(!"Switching for iAP2 Bluetooth is not supported.");
+}
+
+DeviceType IAP2BluetoothEmulationTransportAdapter::GetDeviceType() const {
+ return IOS_BT;
+}
+
+IAP2USBEmulationTransportAdapter::IAP2USBEmulationTransportAdapter(
+ const uint16_t port,
+ resumption::LastState& last_state,
+ const TransportManagerSettings& settings)
+ : TcpTransportAdapter(port, last_state, settings), out_(0) {
+ auto delegate = new IAPSignalHandlerDelegate(*this);
+ signal_handler_ = threads::CreateThread("iAP signal handler", delegate);
+ signal_handler_->start();
+ const auto result = mkfifo(out_signals_channel, mode);
+ LOG4CXX_DEBUG(logger_, "Out signals channel creation result: " << result);
+}
+
+IAP2USBEmulationTransportAdapter::~IAP2USBEmulationTransportAdapter() {
+ signal_handler_->join();
+ auto delegate = signal_handler_->delegate();
+ signal_handler_->set_delegate(NULL);
+ delete delegate;
+ 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_);
+
+ if (out_ < 0) {
+ LOG4CXX_ERROR(logger_, "Failed to open out signals channel");
+ return;
+ }
+
+ const auto bytes =
+ write(out_, switch_signal_ack.c_str(), switch_signal_ack.size());
+ UNUSED(bytes);
+ 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");
+ close(out_);
+}
+
+DeviceType IAP2USBEmulationTransportAdapter::GetDeviceType() const {
+ return IOS_USB;
+}
+
+IAP2USBEmulationTransportAdapter::IAPSignalHandlerDelegate::
+ IAPSignalHandlerDelegate(IAP2USBEmulationTransportAdapter& adapter)
+ : adapter_(adapter), run_flag_(true), in_(0) {
+ const auto result = mkfifo(in_signals_channel, mode);
+ LOG4CXX_DEBUG(logger_, "In signals channel creation result: " << result);
+}
+
+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_);
+ if (in_ < 0) {
+ LOG4CXX_ERROR(logger_, "Failed to open in signals channel");
+ return;
+ }
+
+ const auto size = 32;
+ while (run_flag_) {
+ char buffer[size];
+ auto bytes = read(in_, &buffer, size - 1);
+ if (0 == bytes) {
+ continue;
+ }
+ if (-1 == bytes) {
+ LOG4CXX_DEBUG(logger_, "Error during input pipe read");
+ break;
+ }
+ LOG4CXX_DEBUG(logger_, "Read in bytes: " << bytes);
+ buffer[bytes] = '\0';
+ std::string str(buffer);
+ if (std::string::npos != str.find(switch_signal)) {
+ LOG4CXX_DEBUG(logger_, "Switch signal received.");
+ adapter_.DoTransportSwitch();
+ }
+ }
+
+ LOG4CXX_DEBUG(logger_, "In close result: " << close(in_));
+ LOG4CXX_DEBUG(logger_, "In unlink result: " << unlink(in_signals_channel));
+}
+
+void IAP2USBEmulationTransportAdapter::IAPSignalHandlerDelegate::
+ exitThreadMain() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ LOG4CXX_DEBUG(logger_, "Stopping signal handling.");
+ run_flag_ = false;
+ ThreadDelegate::exitThreadMain();
+}
+}
+} // namespace transport_manager::transport_adapter