diff options
Diffstat (limited to 'src/components/transport_manager')
22 files changed, 1599 insertions, 496 deletions
diff --git a/src/components/transport_manager/CMakeLists.txt b/src/components/transport_manager/CMakeLists.txt index e738bbaeb7..4fa224393d 100644 --- a/src/components/transport_manager/CMakeLists.txt +++ b/src/components/transport_manager/CMakeLists.txt @@ -89,6 +89,13 @@ else() ) endif() +if(NOT BUILD_TESTS) + list (APPEND EXCLUDE_PATH + ${CMAKE_CURRENT_SOURCE_DIR}/include/iap2_emulation/iap2_transport_adapter.h + ${CMAKE_CURRENT_SOURCE_DIR}/src/iap2_emulation/iap2_transport_adapter.cc + ) +endif() + collect_sources(SOURCES "${PATHS}" "${EXCLUDE_PATHS}") add_library("TransportManager" ${SOURCES}) 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 new file mode 100644 index 0000000000..36a2b374dd --- /dev/null +++ b/src/components/transport_manager/include/transport_manager/iap2_emulation/iap2_transport_adapter.h @@ -0,0 +1,165 @@ +/* + * 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. + */ + +#ifndef SRC_COMPONENTS_TRANSPORT_MANAGER_INCLUDE_TRANSPORT_MANAGER_IAP2_EMULATION_IAP2_TRANSPORT_ADAPTER_H_ +#define SRC_COMPONENTS_TRANSPORT_MANAGER_INCLUDE_TRANSPORT_MANAGER_IAP2_EMULATION_IAP2_TRANSPORT_ADAPTER_H_ + +#include "transport_manager/tcp/tcp_transport_adapter.h" +#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 { + +/** + * @brief The IAP2BluetoothEmulationTransportAdapter class implements iAP2 + * Bluetooth transport over TCP + */ +class IAP2BluetoothEmulationTransportAdapter : public TcpTransportAdapter { + public: + /** + * @brief IAP2BluetoothEmulationTransportAdapter constructor + * @param port TCP port to listen on + * @param last_state LastState instance reference + * @param settings Settings reference + */ + IAP2BluetoothEmulationTransportAdapter( + const uint16_t port, + resumption::LastState& last_state, + const TransportManagerSettings& settings); + + /** + * @brief DeviceSwitched is called during switching from iAP2 Bluetooth to + * iAP2 USB transport. + * Currently there is no logic to switch back from iAP2 USB to iAP2 Bluetooth + * due to Bluetooth reconnection takes much time and this violates some Apple + * restrictions for iAP2 protocol, so if this method will be called - assert + * will be called + * @param device_handle Device handle of switched device + */ + void DeviceSwitched(const DeviceUID& device_handle) OVERRIDE; + + protected: + /** + * @brief GetDeviceType Provides SDL device type for transport adapter + * @return Device type + */ + DeviceType GetDeviceType() const OVERRIDE; +}; + +/** + * @brief The IAP2USBEmulationTransportAdapter class implements emulation of + * iAP2 USB transport over TCP + */ +class IAP2USBEmulationTransportAdapter : public TcpTransportAdapter { + public: + /** + * @brief IAP2USBEmulationTransportAdapter constructor + * @param port TCP port to listen on + * @param last_state LastState instance reference + * @param settings Settings reference + */ + IAP2USBEmulationTransportAdapter(const uint16_t port, + resumption::LastState& last_state, + const TransportManagerSettings& settings); + + /** + * Destructor + */ + ~IAP2USBEmulationTransportAdapter(); + + /** + * @brief DeviceSwitched is called during switching from iAP2 Bluetooth to + * iAP2 USB transport. Sends ACK signal for switching request. + * @param device_handle Device handle of switched device + */ + void DeviceSwitched(const DeviceUID& device_handle) OVERRIDE; + + protected: + /** + * @brief GetDeviceType Provides SDL device type for transport adapter + * @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: + /** + * @brief adapter_ Reference to owning adapter + */ + IAP2USBEmulationTransportAdapter& adapter_; + + /** + * @brief run_flag_ Flag defines whether main loop is active + */ + bool run_flag_; + + /** + * @brief in_ Input signals channel descriptor + */ + int in_; + }; + + threads::Thread* signal_handler_; + int out_; +}; +} // namespace transport_adapter +} // namespace transport_manager +#endif // SRC_COMPONENTS_TRANSPORT_MANAGER_INCLUDE_TRANSPORT_MANAGER_IAP2_EMULATION_IAP2_TRANSPORT_ADAPTER_H_ 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..7aa0b72687 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/include/transport_manager/transport_adapter/transport_adapter_impl.h b/src/components/transport_manager/include/transport_manager/transport_adapter/transport_adapter_impl.h index d4c97d5233..2b1ada79ad 100644 --- a/src/components/transport_manager/include/transport_manager/transport_adapter/transport_adapter_impl.h +++ b/src/components/transport_manager/include/transport_manager/transport_adapter/transport_adapter_impl.h @@ -400,6 +400,26 @@ class TransportAdapterImpl : public TransportAdapter, const DataSendError& error) OVERRIDE; /** + * @brief DoTransportSwitch notifies listeners of transport adapter events + * that transport switching is requested by system + */ + void DoTransportSwitch() const OVERRIDE; + + /** + * @brief DeviceSwitched Notifies system on successful transport switch for + * particular device + * @param device_handle Device handle of switched device + */ + void DeviceSwitched(const DeviceUID& device_handle) OVERRIDE; + + /** + * @brief GetSwitchableDevices Provides list of devices able to switch their + * transport (e.g. iAP2 Bluetooth to iAP2 USB). + * @return + */ + SwitchableDevices GetSwitchableDevices() const OVERRIDE; + + /** * @brief Return name of device. * * @param device_id Device unique identifier. @@ -409,6 +429,13 @@ class TransportAdapterImpl : public TransportAdapter, std::string DeviceName(const DeviceUID& device_id) const OVERRIDE; /** + * @brief StopDevice looks for specific device in devices list and calls + * Stop() interface of that device + * @param device_id unique device identifier that has to be stopped. + */ + void StopDevice(const DeviceUID& device_id) const OVERRIDE; + + /** * @brief Allows to obtain connection type used by device. * @return connection type. */ diff --git a/src/components/transport_manager/include/transport_manager/transport_adapter/transport_adapter_listener.h b/src/components/transport_manager/include/transport_manager/transport_adapter/transport_adapter_listener.h index 0a1eeb6b4a..424fa53dea 100644 --- a/src/components/transport_manager/include/transport_manager/transport_adapter/transport_adapter_listener.h +++ b/src/components/transport_manager/include/transport_manager/transport_adapter/transport_adapter_listener.h @@ -146,6 +146,7 @@ class TransportAdapterListener { const DeviceUID& device_handle, const ApplicationHandle& app_handle, const CommunicationError& error) = 0; + /** * @brief Search specified device adapter in the container of shared pointers *to device adapters to be sure it is available, @@ -269,6 +270,13 @@ class TransportAdapterListener { virtual void OnCommunicationError(const TransportAdapter* transport_adapter, const DeviceUID& device_handle, const ApplicationHandle& app_handle) = 0; + /** + * @brief OnTransportSwitchRequested notifies on received signal to start + * transport switching flow (at the moment Bluetooth to USB only) + * @param transport_adapter Transport adapter who received the signal + */ + virtual void OnTransportSwitchRequested( + const TransportAdapter* transport_adapter) = 0; }; } // transport_adapter namespace diff --git a/src/components/transport_manager/include/transport_manager/transport_adapter/transport_adapter_listener_impl.h b/src/components/transport_manager/include/transport_manager/transport_adapter/transport_adapter_listener_impl.h index a7cd544563..8a8031c3cf 100644 --- a/src/components/transport_manager/include/transport_manager/transport_adapter/transport_adapter_listener_impl.h +++ b/src/components/transport_manager/include/transport_manager/transport_adapter/transport_adapter_listener_impl.h @@ -49,26 +49,6 @@ class TransportAdapterListenerImpl : public transport_adapter::TransportAdapterListener { public: /** - * @enum Available types of events. - */ - enum EventTypeEnum { - ON_SEARCH_DONE = 0, - ON_SEARCH_FAIL, - ON_DEVICE_LIST_UPDATED, - ON_FIND_NEW_APPLICATIONS_REQUEST, - ON_CONNECT_DONE, - ON_CONNECT_FAIL, - ON_DISCONNECT_DONE, - ON_DISCONNECT_FAIL, - ON_SEND_DONE, - ON_SEND_FAIL, - ON_RECEIVED_DONE, - ON_RECEIVED_FAIL, - ON_COMMUNICATION_ERROR, - ON_UNEXPECTED_DISCONNECT - }; - - /** * @brief Constructor. * * @param manager Pointer to the transport manager class. @@ -283,7 +263,14 @@ class TransportAdapterListenerImpl */ virtual void OnCommunicationError(const TransportAdapter* adapter, const DeviceUID& device, - const ApplicationHandle& app_id); + const ApplicationHandle& app_id) OVERRIDE; + + /** + * @brief OnTransportSwitchRequested notifies on received signal to start + * transport switching flow (at the moment Bluetooth to USB only) + * @param transport_adapter Transport adapter who received the signal + */ + void OnTransportSwitchRequested(const TransportAdapter* adapter) OVERRIDE; private: TransportManager* transport_manager_; diff --git a/src/components/transport_manager/include/transport_manager/transport_manager_impl.h b/src/components/transport_manager/include/transport_manager/transport_manager_impl.h index 4dd74086be..eaa71ce3bb 100644 --- a/src/components/transport_manager/include/transport_manager/transport_manager_impl.h +++ b/src/components/transport_manager/include/transport_manager/transport_manager_impl.h @@ -39,6 +39,8 @@ #include <vector> #include <utility> #include <algorithm> +#include <tuple> +#include <functional> #include "utils/timer.h" #include "utils/timer_task_impl.h" @@ -63,6 +65,7 @@ typedef threads::MessageLoopThread<std::queue<protocol_handler::RawMessagePtr> > typedef threads::MessageLoopThread<std::queue<TransportAdapterEvent> > TransportAdapterEventLoopThread; typedef utils::SharedPtr<timer::Timer> TimerSPtr; +typedef std::map<DeviceUID, TransportAdapter*> DeviceToAdapterMap; /** * @brief Implementation of transport manager.s @@ -94,6 +97,7 @@ class TransportManagerImpl bool shutdown_; DeviceHandle device_handle_; int messages_count; + bool active_; ConnectionInternal(TransportManagerImpl* transport_manager, TransportAdapter* transport_adapter, @@ -241,11 +245,20 @@ class TransportManagerImpl int Visibility(const bool& on_off) const OVERRIDE; /** + * DEPRECATED + * Must be moved under 'private' section * @brief Updates total device list with info from specific transport adapter. * @param ta Transport adapter */ void UpdateDeviceList(TransportAdapter* ta); + /** + * @brief OnDeviceListUpdated updates device list and sends appropriate + * notifications to listeners in case of something is changed + * @param ta Transport adapter to check for updated devices state + */ + void OnDeviceListUpdated(TransportAdapter* ta); + #ifdef TELEMETRY_MONITOR /** * @brief Setup observer for time metric. @@ -307,44 +320,53 @@ class TransportManagerImpl private: /** - * @brief Structure that contains conversion functions (Device ID -> Device - * Handle; Device Handle -> Device ID) - */ + * @brief Structure that contains conversion functions (Device ID -> Device + * Handle; Device Handle -> Device ID) + */ struct Handle2GUIDConverter { - typedef std::vector<DeviceUID> ConversionTable; - - DeviceHandle UidToHandle(const DeviceUID& dev_uid) { - bool is_new = true; - return UidToHandle(dev_uid, is_new); - } - - DeviceHandle UidToHandle(const DeviceUID& dev_uid, bool& is_new) { - { - sync_primitives::AutoReadLock lock(conversion_table_lock); - ConversionTable::iterator it = std::find( - conversion_table_.begin(), conversion_table_.end(), dev_uid); - if (it != conversion_table_.end()) { - is_new = false; - return std::distance(conversion_table_.begin(), it) + - 1; // handle begin since 1 (one) - } + /** + * @brief ConversionTable Records uid/connection type/handle + */ + typedef std::vector<std::tuple<DeviceUID, std::string, DeviceHandle> > + ConversionTable; + + /** + * @brief The HandleFinder struct helper to search for hanlde in coversion + * table + */ + struct HandleFinder { + explicit HandleFinder(const DeviceHandle& look_for) + : look_for_(look_for) {} + + bool operator()(const ConversionTable::value_type value) const { + return look_for_ == std::get<2>(value); } - is_new = true; - sync_primitives::AutoWriteLock lock(conversion_table_lock); - conversion_table_.push_back(dev_uid); - return conversion_table_.size(); // handle begin since 1 (one) - } - - DeviceUID HandleToUid(const DeviceHandle handle) { - sync_primitives::AutoReadLock lock(conversion_table_lock); - if (handle == 0 || handle > conversion_table_.size()) { - return DeviceUID(); - } - return conversion_table_[handle - 1]; // handle begin since 1 (one) - } + const DeviceHandle look_for_; + }; + + /** + * @brief UidToHandle Converts UID to handle considering connection type as + * UID may be the same in case device is connected over Bluetooth/USB (e.g. + * for IAP2) + * @param dev_uid Device UID + * @param connection_type Connection type + * @return Device handle + */ + DeviceHandle UidToHandle(const DeviceUID& dev_uid, + const std::string& connection_type); + + /** + * @brief HandleToUid Converts handle to device UID + * @param handle Device handle + * @return Device UID + */ + DeviceUID HandleToUid(const DeviceHandle handle); + + private: ConversionTable conversion_table_; - sync_primitives::RWLock conversion_table_lock; + std::hash<std::string> hash_function_; + sync_primitives::RWLock conversion_table_lock_; }; /** @@ -353,6 +375,15 @@ class TransportManagerImpl */ Handle2GUIDConverter converter_; +#ifdef BUILD_TESTS + public: + Handle2GUIDConverter& get_converter() { + return converter_; + } + + private: +#endif // BUILD_TESTS + explicit TransportManagerImpl(const TransportManagerImpl&); int connection_id_counter_; sync_primitives::RWLock connections_lock_; @@ -372,13 +403,70 @@ class TransportManagerImpl sync_primitives::RWLock device_list_lock_; DeviceInfoList device_list_; + timer::Timer device_switch_timer_; + sync_primitives::Lock device_lock_; + DeviceUID device_to_reconnect_; + + /** + * @brief Adds new incoming connection to connections list + * @param c New connection + */ void AddConnection(const ConnectionInternal& c); + + /** + * @brief Removes connection from connections list + * @param id Identifier of connection to be removed + * @param transport_adapter Pointer to transport adapter + * that holds connection + */ void RemoveConnection(const uint32_t id, transport_adapter::TransportAdapter* transport_adapter); + + /** + * @brief Deactivates all connections related to certain device + * @param device_uid Device unique identifier + */ + void DeactivateDeviceConnections(const DeviceUID& device_uid); + /** + * @brief Returns connection from connections list by connection identifier + * @param id Connection identifier + * @return Pointer to connection or NULL if connection could not be found + */ ConnectionInternal* GetConnection(const ConnectionUID id); + + /** + * @brief Returns connection from connections list by device unique id + * and application handle + * @param device Device unique identifier + * @param application Application handle + * @return Pointer to connection or NULL if connection could not be found + */ ConnectionInternal* GetConnection(const DeviceUID& device, const ApplicationHandle& application); + /** + * @brief Returns active connection from connections list by device unique + * id + * and application handle + * (this method returns only active connections as opposed to previous one) + * @param device Device unique identifier + * @param application Application handle + * @return Pointer to connection or NULL if connection could not be found + */ + ConnectionInternal* GetActiveConnection(const DeviceUID& device, + const ApplicationHandle& application); + + /** + * @brief TryDeviceSwitch in case USB device is connected and there is + * appropriate Bluetooth device with same UUID stops Bluetooth device and + * initiates switching sequence for upper layers. Also starts timer to wait + * for sequence to complete. + * @param ta Transport adapter having device to try switching sequence + * At the moment implementation implies only IAP2-Bluetooth to IAP2-USB + * switching + */ + void TryDeviceSwitch(TransportAdapter* ta); + void AddDataToContainer( ConnectionUID id, std::map<ConnectionUID, std::pair<unsigned int, unsigned char*> >& @@ -394,11 +482,25 @@ class TransportManagerImpl unsigned int frame_size, unsigned char** frame); - void OnDeviceListUpdated(TransportAdapter* ta); void DisconnectAllDevices(); void TerminateAllAdapters(); int InitAllAdapters(); static Connection convert(const ConnectionInternal& p); + + /** + * @brief ReconnectionTimeout notifies upper layers on switching sequence + * timeout expiration + */ + void ReconnectionTimeout(); + + /** + * @brief UpdateDeviceMapping handles internal device-to-adapter mapping, + * performs its update on adding/removal of devices. Also used by IAP2 + * switching flow to substitute BT with USB transport + * @param ta Pointer to transport adapter + * @return True if mapping has been updated, otherwise - false + */ + bool UpdateDeviceMapping(TransportAdapter* ta); }; // class TransportManagerImpl } // namespace transport_manager #endif // SRC_COMPONENTS_TRANSPORT_MANAGER_INCLUDE_TRANSPORT_MANAGER_TRANSPORT_MANAGER_IMPL_H_ diff --git a/src/components/transport_manager/include/transport_manager/usb/libusb/usb_connection.h b/src/components/transport_manager/include/transport_manager/usb/libusb/usb_connection.h index bad1cd7117..5f6bd40957 100644 --- a/src/components/transport_manager/include/transport_manager/usb/libusb/usb_connection.h +++ b/src/components/transport_manager/include/transport_manager/usb/libusb/usb_connection.h @@ -80,6 +80,7 @@ class UsbConnection : public Connection { uint8_t out_endpoint_; uint16_t out_endpoint_max_packet_size_; unsigned char* in_buffer_; + uint16_t in_buffer_size_; libusb_transfer* in_transfer_; libusb_transfer* out_transfer_; 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..741c075310 --- /dev/null +++ b/src/components/transport_manager/src/iap2_emulation/iap2_transport_adapter.cc @@ -0,0 +1,163 @@ +/* + * 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_); + + 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"); +} + +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_); + + const auto size = 32; + while (run_flag_) { + char buffer[size]; + auto bytes = read(in_, &buffer, size); + if (0 == bytes) { + continue; + } + if (-1 == bytes) { + LOG4CXX_DEBUG(logger_, "Error during input pipe read"); + break; + } + 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(); + } + } + + 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 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 52a566c5ff..207149eb8c 100644 --- a/src/components/transport_manager/src/tcp/tcp_client_listener.cc +++ b/src/components/transport_manager/src/tcp/tcp_client_listener.cc @@ -230,13 +230,23 @@ void TcpClientListener::Loop() { 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); } + 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); +#else TcpDevice* tcp_device = - new TcpDevice(client_address.sin_addr.s_addr, device_name); + new 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 = diff --git a/src/components/transport_manager/src/tcp/tcp_device.cc b/src/components/transport_manager/src/tcp/tcp_device.cc index d3f132759a..dbcb5d38cb 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); 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 026e53670b..9fb0921c4b 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 @@ -45,13 +45,16 @@ namespace transport_adapter { CREATE_LOGGERPTR_GLOBAL(logger_, "TransportManager") namespace { +// @deprecated DeviceTypes: PASA_AOA, PASA_BLUETOOTH, MME DeviceTypes devicesType = { - std::make_pair(AOA, std::string("USB_AOA")), - std::make_pair(PASA_AOA, std::string("USB_AOA")), - std::make_pair(MME, std::string("USB_IOS")), - std::make_pair(BLUETOOTH, std::string("BLUETOOTH")), - std::make_pair(PASA_BLUETOOTH, std::string("BLUETOOTH")), - std::make_pair(TCP, std::string("WIFI"))}; + 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"))}; } TransportAdapterImpl::TransportAdapterImpl( @@ -502,15 +505,13 @@ void TransportAdapterImpl::SearchDeviceFailed(const SearchDeviceError& error) { } bool TransportAdapterImpl::IsSearchDevicesSupported() const { - LOG4CXX_TRACE(logger_, "enter"); + LOG4CXX_AUTO_TRACE(logger_); return device_scanner_ != 0; - LOG4CXX_TRACE(logger_, "exit"); } bool TransportAdapterImpl::IsServerOriginatedConnectSupported() const { - LOG4CXX_TRACE(logger_, "enter"); + LOG4CXX_AUTO_TRACE(logger_); return server_connection_factory_ != 0; - LOG4CXX_TRACE(logger_, "exit"); } bool TransportAdapterImpl::IsClientOriginatedConnectSupported() const { @@ -694,6 +695,23 @@ void TransportAdapterImpl::DataSendFailed( LOG4CXX_TRACE(logger_, "exit"); } +void TransportAdapterImpl::DoTransportSwitch() const { + LOG4CXX_AUTO_TRACE(logger_); + std::for_each( + listeners_.begin(), + listeners_.end(), + std::bind2nd( + std::mem_fun(&TransportAdapterListener::OnTransportSwitchRequested), + this)); +} + +void TransportAdapterImpl::DeviceSwitched(const DeviceUID& device_handle) { + LOG4CXX_DEBUG(logger_, + "Switching is not implemented for that adapter type " + << GetConnectionType().c_str()); + UNUSED(device_handle); +} + DeviceSptr TransportAdapterImpl::FindDevice(const DeviceUID& device_id) const { LOG4CXX_TRACE(logger_, "enter. device_id: " << &device_id); DeviceSptr ret; @@ -864,10 +882,40 @@ std::string TransportAdapterImpl::DeviceName(const DeviceUID& device_id) const { } } +void TransportAdapterImpl::StopDevice(const DeviceUID& device_id) const { + LOG4CXX_AUTO_TRACE(logger_); + DeviceSptr device = FindDevice(device_id); + if (device) { + device->Stop(); + } +} + std::string TransportAdapterImpl::GetConnectionType() const { return devicesType[GetDeviceType()]; } +SwitchableDevices TransportAdapterImpl::GetSwitchableDevices() const { + LOG4CXX_AUTO_TRACE(logger_); + SwitchableDevices devices; + sync_primitives::AutoLock locker(devices_mutex_); + for (DeviceMap::const_iterator it = devices_.begin(); it != devices_.end(); + ++it) { + const auto device_uid = it->first; + const auto device = it->second; + const auto transport_switch_id = device->transport_switch_id(); + if (transport_switch_id.empty()) { + LOG4CXX_DEBUG(logger_, + "Device is not suitable for switching: " << device_uid); + continue; + } + LOG4CXX_DEBUG(logger_, "Device is suitable for switching: " << device_uid); + devices.insert(std::make_pair(device_uid, transport_switch_id)); + } + LOG4CXX_INFO(logger_, + "Found number of switchable devices: " << devices.size()); + return devices; +} + #ifdef TELEMETRY_MONITOR void TransportAdapterImpl::SetTelemetryObserver(TMTelemetryObserver* observer) { metric_observer_ = observer; 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 2ab19ade86..f1181ce921 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 @@ -48,13 +48,12 @@ TransportAdapterListenerImpl::TransportAdapterListenerImpl( void TransportAdapterListenerImpl::OnSearchDeviceDone( const TransportAdapter* adapter) { LOG4CXX_TRACE(logger_, "enter. adapter* " << adapter); - const TransportAdapterEvent event( - TransportAdapterListenerImpl::EventTypeEnum::ON_SEARCH_DONE, - transport_adapter_, - "", - 0, - ::protocol_handler::RawMessagePtr(), - BaseErrorPtr()); + const TransportAdapterEvent event(EventTypeEnum::ON_SEARCH_DONE, + transport_adapter_, + "", + 0, + ::protocol_handler::RawMessagePtr(), + BaseErrorPtr()); if (transport_manager_ != NULL && transport_manager::E_SUCCESS != transport_manager_->ReceiveEventFromDevice(event)) { @@ -68,13 +67,12 @@ void TransportAdapterListenerImpl::OnSearchDeviceFailed( LOG4CXX_TRACE(logger_, "enter. adapter: " << adapter << ", error: " << &error); SearchDeviceError* err = new SearchDeviceError(error); - const TransportAdapterEvent event( - TransportAdapterListenerImpl::EventTypeEnum::ON_SEARCH_FAIL, - transport_adapter_, - "", - 0, - ::protocol_handler::RawMessagePtr(), - BaseErrorPtr(err)); + const TransportAdapterEvent event(EventTypeEnum::ON_SEARCH_FAIL, + transport_adapter_, + "", + 0, + ::protocol_handler::RawMessagePtr(), + BaseErrorPtr(err)); if (transport_manager_ != NULL && transport_manager::E_SUCCESS != transport_manager_->ReceiveEventFromDevice(event)) { @@ -86,13 +84,12 @@ void TransportAdapterListenerImpl::OnSearchDeviceFailed( void TransportAdapterListenerImpl::OnDeviceListUpdated( const TransportAdapter* adapter) { LOG4CXX_TRACE(logger_, "enter. adapter* " << adapter); - const TransportAdapterEvent event( - TransportAdapterListenerImpl::EventTypeEnum::ON_DEVICE_LIST_UPDATED, - transport_adapter_, - "", - 0, - ::protocol_handler::RawMessagePtr(), - BaseErrorPtr()); + const TransportAdapterEvent event(EventTypeEnum::ON_DEVICE_LIST_UPDATED, + transport_adapter_, + "", + 0, + ::protocol_handler::RawMessagePtr(), + BaseErrorPtr()); if (transport_manager_ != NULL && transport_manager::E_SUCCESS != transport_manager_->ReceiveEventFromDevice(event)) { @@ -105,7 +102,7 @@ void TransportAdapterListenerImpl::OnFindNewApplicationsRequest( const TransportAdapter* adapter) { LOG4CXX_TRACE(logger_, "enter. adapter* " << adapter); const TransportAdapterEvent event( - TransportAdapterListenerImpl::ON_FIND_NEW_APPLICATIONS_REQUEST, + EventTypeEnum::ON_FIND_NEW_APPLICATIONS_REQUEST, transport_adapter_, "", 0, @@ -126,13 +123,12 @@ void TransportAdapterListenerImpl::OnConnectDone( LOG4CXX_TRACE(logger_, "enter adapter*: " << adapter << ", device: " << &device << ", application_id: " << &application_id); - const TransportAdapterEvent event( - TransportAdapterListenerImpl::EventTypeEnum::ON_CONNECT_DONE, - transport_adapter_, - device, - application_id, - ::protocol_handler::RawMessagePtr(), - BaseErrorPtr(new BaseError())); + const TransportAdapterEvent event(EventTypeEnum::ON_CONNECT_DONE, + transport_adapter_, + device, + application_id, + ::protocol_handler::RawMessagePtr(), + BaseErrorPtr(new BaseError())); if (transport_manager_ != NULL && transport_manager::E_SUCCESS != transport_manager_->ReceiveEventFromDevice(event)) { @@ -151,13 +147,12 @@ void TransportAdapterListenerImpl::OnConnectFailed( << ", application_id: " << &app_id << ", error: " << &error); ConnectError* err = new ConnectError(error); - const TransportAdapterEvent event( - TransportAdapterListenerImpl::EventTypeEnum::ON_CONNECT_FAIL, - transport_adapter_, - device, - app_id, - ::protocol_handler::RawMessagePtr(), - BaseErrorPtr(err)); + const TransportAdapterEvent event(EventTypeEnum::ON_CONNECT_FAIL, + transport_adapter_, + device, + app_id, + ::protocol_handler::RawMessagePtr(), + BaseErrorPtr(err)); if (transport_manager_ != NULL && transport_manager::E_SUCCESS != transport_manager_->ReceiveEventFromDevice(event)) { @@ -173,13 +168,12 @@ void TransportAdapterListenerImpl::OnDisconnectDone( LOG4CXX_TRACE(logger_, "enter. adapter: " << adapter << ", device: " << &device << ", application_id: " << &app_id); - const TransportAdapterEvent event( - TransportAdapterListenerImpl::EventTypeEnum::ON_DISCONNECT_DONE, - transport_adapter_, - device, - app_id, - ::protocol_handler::RawMessagePtr(), - BaseErrorPtr(new BaseError())); + const TransportAdapterEvent event(EventTypeEnum::ON_DISCONNECT_DONE, + transport_adapter_, + device, + app_id, + ::protocol_handler::RawMessagePtr(), + BaseErrorPtr(new BaseError())); if (transport_manager_ != NULL && transport_manager::E_SUCCESS != transport_manager_->ReceiveEventFromDevice(event)) { @@ -198,13 +192,12 @@ void TransportAdapterListenerImpl::OnDisconnectFailed( << ", application_id: " << &app_id << ", error: " << &error); DisconnectError* err = new DisconnectError(error); - const TransportAdapterEvent event( - TransportAdapterListenerImpl::EventTypeEnum::ON_DISCONNECT_FAIL, - transport_adapter_, - device, - app_id, - ::protocol_handler::RawMessagePtr(), - BaseErrorPtr(err)); + const TransportAdapterEvent event(EventTypeEnum::ON_DISCONNECT_FAIL, + transport_adapter_, + device, + app_id, + ::protocol_handler::RawMessagePtr(), + BaseErrorPtr(err)); if (transport_manager_ != NULL && transport_manager::E_SUCCESS != transport_manager_->ReceiveEventFromDevice(event)) { @@ -230,13 +223,12 @@ void TransportAdapterListenerImpl::OnDataReceiveDone( "enter. adapter: " << adapter << ", device: " << &device << ", application_id: " << &app_id << ", data_container: " << data_container); - const TransportAdapterEvent event( - TransportAdapterListenerImpl::EventTypeEnum::ON_RECEIVED_DONE, - transport_adapter_, - device, - app_id, - data_container, - BaseErrorPtr(new BaseError())); + const TransportAdapterEvent event(EventTypeEnum::ON_RECEIVED_DONE, + transport_adapter_, + device, + app_id, + data_container, + BaseErrorPtr(new BaseError())); if (transport_manager_ != NULL && transport_manager::E_SUCCESS != transport_manager_->ReceiveEventFromDevice(event)) { @@ -255,13 +247,12 @@ void TransportAdapterListenerImpl::OnDataReceiveFailed( << ", application_id: " << &app_id << ", error: " << &error); DataReceiveError* err = new DataReceiveError(error); - const TransportAdapterEvent event( - TransportAdapterListenerImpl::EventTypeEnum::ON_RECEIVED_FAIL, - transport_adapter_, - device, - app_id, - ::protocol_handler::RawMessagePtr(), - BaseErrorPtr(err)); + const TransportAdapterEvent event(EventTypeEnum::ON_RECEIVED_FAIL, + transport_adapter_, + device, + app_id, + ::protocol_handler::RawMessagePtr(), + BaseErrorPtr(err)); if (transport_manager_ != NULL && transport_manager::E_SUCCESS != transport_manager_->ReceiveEventFromDevice(event)) { @@ -279,13 +270,12 @@ void TransportAdapterListenerImpl::OnDataSendDone( "enter. adapter: " << adapter << ", device: " << &device << ", application_id: " << &app_id << ", data_container: " << data_container); - const TransportAdapterEvent event( - TransportAdapterListenerImpl::EventTypeEnum::ON_SEND_DONE, - transport_adapter_, - device, - app_id, - data_container, - new BaseError()); + const TransportAdapterEvent event(EventTypeEnum::ON_SEND_DONE, + transport_adapter_, + device, + app_id, + data_container, + new BaseError()); if (transport_manager_ != NULL && transport_manager::E_SUCCESS != transport_manager_->ReceiveEventFromDevice(event)) { @@ -306,13 +296,12 @@ void TransportAdapterListenerImpl::OnDataSendFailed( << ", data_container: " << data_container << ", error: " << &error); DataSendError* err = new DataSendError(error); - const TransportAdapterEvent event( - TransportAdapterListenerImpl::EventTypeEnum::ON_SEND_FAIL, - transport_adapter_, - device, - app_id, - data_container, - BaseErrorPtr(err)); + const TransportAdapterEvent event(EventTypeEnum::ON_SEND_FAIL, + transport_adapter_, + device, + app_id, + data_container, + BaseErrorPtr(err)); if (transport_manager_ != NULL && transport_manager::E_SUCCESS != transport_manager_->ReceiveEventFromDevice(event)) { @@ -336,13 +325,12 @@ void TransportAdapterListenerImpl::OnUnexpectedDisconnect( << ", application: " << &application << ", error: " << &error); CommunicationError* err = new CommunicationError(error); - const TransportAdapterEvent event( - TransportAdapterListenerImpl::EventTypeEnum::ON_UNEXPECTED_DISCONNECT, - transport_adapter_, - device, - application, - ::protocol_handler::RawMessagePtr(), - BaseErrorPtr(err)); + const TransportAdapterEvent event(EventTypeEnum::ON_UNEXPECTED_DISCONNECT, + transport_adapter_, + device, + application, + ::protocol_handler::RawMessagePtr(), + BaseErrorPtr(err)); if (transport_manager_ != NULL && transport_manager::E_SUCCESS != transport_manager_->ReceiveEventFromDevice(event)) { @@ -358,18 +346,34 @@ void TransportAdapterListenerImpl::OnCommunicationError( LOG4CXX_TRACE(logger_, "enter. adapter: " << adapter << ", device: " << &device << ", application_id: " << &app_id); + const TransportAdapterEvent event(EventTypeEnum::ON_COMMUNICATION_ERROR, + transport_adapter_, + device, + app_id, + ::protocol_handler::RawMessagePtr(), + BaseErrorPtr(new BaseError())); + if (transport_manager_ != NULL && + transport_manager::E_SUCCESS != + transport_manager_->ReceiveEventFromDevice(event)) { + LOG4CXX_WARN(logger_, "Failed to receive event from device"); + } + LOG4CXX_TRACE(logger_, "exit"); +} + +void TransportAdapterListenerImpl::OnTransportSwitchRequested( + const transport_adapter::TransportAdapter* adapter) { + LOG4CXX_AUTO_TRACE(logger_); const TransportAdapterEvent event( - TransportAdapterListenerImpl::EventTypeEnum::ON_COMMUNICATION_ERROR, + EventTypeEnum::ON_TRANSPORT_SWITCH_REQUESTED, transport_adapter_, - device, - app_id, + "", + 0, ::protocol_handler::RawMessagePtr(), - BaseErrorPtr(new BaseError())); + BaseErrorPtr()); if (transport_manager_ != NULL && transport_manager::E_SUCCESS != transport_manager_->ReceiveEventFromDevice(event)) { LOG4CXX_WARN(logger_, "Failed to receive event from device"); } - LOG4CXX_TRACE(logger_, "exit"); } } // namespace transport_manager diff --git a/src/components/transport_manager/src/transport_manager_default.cc b/src/components/transport_manager/src/transport_manager_default.cc index 31f398233b..196ad09af4 100644 --- a/src/components/transport_manager/src/transport_manager_default.cc +++ b/src/components/transport_manager/src/transport_manager_default.cc @@ -44,6 +44,10 @@ #include "transport_manager/usb/usb_aoa_adapter.h" #endif // USB_SUPPORT +#if defined(BUILD_TESTS) +#include "transport_manager/iap2_emulation/iap2_transport_adapter.h" +#endif // BUILD_TEST + namespace transport_manager { CREATE_LOGGERPTR_GLOBAL(logger_, "TransportManager") @@ -97,6 +101,23 @@ int TransportManagerDefault::Init(resumption::LastState& last_state) { ta_usb = NULL; #endif // USB_SUPPORT +#if defined BUILD_TESTS + const uint16_t iap2_bt_emu_port = 23456; + transport_adapter::IAP2BluetoothEmulationTransportAdapter* + iap2_bt_emu_adapter = + new transport_adapter::IAP2BluetoothEmulationTransportAdapter( + iap2_bt_emu_port, last_state, get_settings()); + + AddTransportAdapter(iap2_bt_emu_adapter); + + const uint16_t iap2_usb_emu_port = 34567; + transport_adapter::IAP2USBEmulationTransportAdapter* iap2_usb_emu_adapter = + new transport_adapter::IAP2USBEmulationTransportAdapter( + iap2_usb_emu_port, last_state, get_settings()); + + AddTransportAdapter(iap2_usb_emu_adapter); +#endif // BUILD_TEST + LOG4CXX_TRACE(logger_, "exit with E_SUCCESS"); return E_SUCCESS; } diff --git a/src/components/transport_manager/src/transport_manager_impl.cc b/src/components/transport_manager/src/transport_manager_impl.cc index 831ff0980e..03e6bd58f6 100644 --- a/src/components/transport_manager/src/transport_manager_impl.cc +++ b/src/components/transport_manager/src/transport_manager_impl.cc @@ -55,6 +55,17 @@ using ::transport_manager::transport_adapter::TransportAdapter; +namespace { +struct ConnectionFinder { + const uint32_t id_; + explicit ConnectionFinder(const uint32_t id) : id_(id) {} + bool operator()(const transport_manager::TransportManagerImpl::Connection& + connection) const { + return id_ == connection.id; + } +}; +} // namespace + namespace transport_manager { CREATE_LOGGERPTR_GLOBAL(logger_, "TransportManager") @@ -82,7 +93,11 @@ TransportManagerImpl::TransportManagerImpl( , connection_id_counter_(0) , message_queue_("TM MessageQueue", this) , event_queue_("TM EventQueue", this) - , settings_(settings) { + , settings_(settings) + , device_switch_timer_( + "Device reconection timer", + new timer::TimerTaskImpl<TransportManagerImpl>( + this, &TransportManagerImpl::ReconnectionTimeout)) { LOG4CXX_TRACE(logger_, "TransportManager has created"); } @@ -108,6 +123,12 @@ TransportManagerImpl::~TransportManagerImpl() { LOG4CXX_INFO(logger_, "TransportManager object destroyed"); } +void TransportManagerImpl::ReconnectionTimeout() { + LOG4CXX_AUTO_TRACE(logger_); + RaiseEvent(&TransportManagerListener::OnDeviceSwitchingFinish, + device_to_reconnect_); +} + int TransportManagerImpl::ConnectDevice(const DeviceHandle device_handle) { LOG4CXX_TRACE(logger_, "enter. DeviceHandle: " << &device_handle); if (!this->is_initialized_) { @@ -562,7 +583,8 @@ void TransportManagerImpl::UpdateDeviceList(TransportAdapter* ta) { const DeviceList dev_list = ta->GetDeviceList(); for (DeviceList::const_iterator it = dev_list.begin(); it != dev_list.end(); ++it) { - DeviceHandle device_handle = converter_.UidToHandle(*it); + DeviceHandle device_handle = + converter_.UidToHandle(*it, ta->GetConnectionType()); DeviceInfo info( device_handle, *it, ta->DeviceName(*it), ta->GetConnectionType()); device_list_.push_back(std::make_pair(ta, info)); @@ -626,25 +648,43 @@ void TransportManagerImpl::RemoveConnection( LOG4CXX_AUTO_TRACE(logger_); LOG4CXX_DEBUG(logger_, "Id: " << id); sync_primitives::AutoWriteLock lock(connections_lock_); - std::vector<ConnectionInternal>::iterator it = connections_.begin(); - while (it != connections_.end()) { - if (it->id == id) { - if (transport_adapter) { - transport_adapter->RemoveFinalizedConnection(it->device, - it->application); - } - connections_.erase(it++); - break; - } else { - ++it; + LOG4CXX_DEBUG(logger_, "Removing connection with id: " << id); + const std::vector<ConnectionInternal>::iterator it = std::find_if( + connections_.begin(), connections_.end(), ConnectionFinder(id)); + if (connections_.end() != it) { + if (transport_adapter) { + transport_adapter->RemoveFinalizedConnection(it->device, it->application); + } + } +} + +void TransportManagerImpl::DeactivateDeviceConnections( + const DeviceUID& device_uid) { + LOG4CXX_AUTO_TRACE(logger_); + + sync_primitives::AutoWriteLock lock(connections_lock_); + LOG4CXX_DEBUG(logger_, + "Deactivating connections for device with UID: " << device_uid); + + size_t counter = 0; + for (std::vector<ConnectionInternal>::iterator it = connections_.begin(); + it != connections_.end(); + ++it) { + if (it->device == device_uid) { + it->active_ = false; + ++counter; } } + LOG4CXX_DEBUG(logger_, + "Deactivated " + << counter + << " connections for device with UID: " << device_uid); } TransportManagerImpl::ConnectionInternal* TransportManagerImpl::GetConnection( const ConnectionUID id) { LOG4CXX_AUTO_TRACE(logger_); - LOG4CXX_DEBUG(logger_, "ConnectionUID: " << &id); + LOG4CXX_DEBUG(logger_, "ConnectionUID: " << id); for (std::vector<ConnectionInternal>::iterator it = connections_.begin(); it != connections_.end(); ++it) { @@ -659,9 +699,8 @@ TransportManagerImpl::ConnectionInternal* TransportManagerImpl::GetConnection( TransportManagerImpl::ConnectionInternal* TransportManagerImpl::GetConnection( const DeviceUID& device, const ApplicationHandle& application) { LOG4CXX_AUTO_TRACE(logger_); - LOG4CXX_DEBUG(logger_, - "DeviceUID: " << &device - << "ApplicationHandle: " << &application); + LOG4CXX_DEBUG( + logger_, "DeviceUID: " << device << "ApplicationHandle: " << application); for (std::vector<ConnectionInternal>::iterator it = connections_.begin(); it != connections_.end(); ++it) { @@ -673,21 +712,201 @@ TransportManagerImpl::ConnectionInternal* TransportManagerImpl::GetConnection( return NULL; } -void TransportManagerImpl::OnDeviceListUpdated(TransportAdapter* ta) { - LOG4CXX_TRACE(logger_, "enter. TransportAdapter: " << ta); - const DeviceList device_list = ta->GetDeviceList(); - LOG4CXX_DEBUG(logger_, "DEVICE_LIST_UPDATED " << device_list.size()); - for (DeviceList::const_iterator it = device_list.begin(); - it != device_list.end(); +TransportManagerImpl::ConnectionInternal* +TransportManagerImpl::GetActiveConnection( + const DeviceUID& device, const ApplicationHandle& application) { + LOG4CXX_AUTO_TRACE(logger_); + LOG4CXX_DEBUG(logger_, + "DeviceUID: " << device + << " ApplicationHandle: " << application); + for (std::vector<ConnectionInternal>::iterator it = connections_.begin(); + it != connections_.end(); + ++it) { + if (it->device == device && it->application == application && it->active_) { + LOG4CXX_DEBUG(logger_, "ConnectionInternal. It's address: " << &*it); + return &*it; + } + } + return NULL; +} + +namespace { + +struct IOSBTAdapterFinder { + bool operator()(const std::vector<TransportAdapter*>::value_type& i) const { + return i->GetDeviceType() == transport_adapter::DeviceType::IOS_BT; + } +}; + +struct SwitchableFinder { + explicit SwitchableFinder(SwitchableDevices::const_iterator what) + : what_(what) {} + bool operator()(const SwitchableDevices::value_type& i) const { + return what_->second == i.second; + } + + private: + SwitchableDevices::const_iterator what_; +}; + +} // namespace + +void TransportManagerImpl::TryDeviceSwitch( + transport_adapter::TransportAdapter* adapter) { + LOG4CXX_AUTO_TRACE(logger_); + if (adapter->GetDeviceType() != transport_adapter::DeviceType::IOS_USB) { + LOG4CXX_ERROR(logger_, "Switching requested not from iAP-USB transport."); + return; + } + + const auto ios_bt_adapter = std::find_if(transport_adapters_.begin(), + transport_adapters_.end(), + IOSBTAdapterFinder()); + + if (transport_adapters_.end() == ios_bt_adapter) { + LOG4CXX_WARN( + logger_, + "There is no iAP2 Bluetooth adapter found. Switching is not possible."); + return; + } + + const SwitchableDevices usb_switchable_devices = + adapter->GetSwitchableDevices(); + const auto bt_switchable_devices = (*ios_bt_adapter)->GetSwitchableDevices(); + auto bt = bt_switchable_devices.end(); + auto usb = usb_switchable_devices.begin(); + for (; usb != usb_switchable_devices.end(); ++usb) { + SwitchableFinder finder(usb); + bt = std::find_if( + bt_switchable_devices.begin(), bt_switchable_devices.end(), finder); + + if (bt != bt_switchable_devices.end()) { + break; + } + } + + if (bt_switchable_devices.end() == bt) { + LOG4CXX_WARN(logger_, + "No suitable for switching iAP2 Bluetooth device found."); + return; + } + + LOG4CXX_DEBUG(logger_, + "Found UUID suitable for transport switching: " << bt->second); + LOG4CXX_DEBUG( + logger_, "Device to switch from: " << bt->first << " to: " << usb->first); + + sync_primitives::AutoWriteLock lock(device_to_adapter_map_lock_); + + const auto bt_device_uid = bt->first; + const auto device_to_switch = device_to_adapter_map_.find(bt_device_uid); + if (device_to_adapter_map_.end() == device_to_switch) { + LOG4CXX_ERROR(logger_, + "There is no known device found with UID " + << bt_device_uid + << " . Transport switching is not possible."); + DCHECK_OR_RETURN_VOID(false); + return; + } + + const auto usb_uid = usb->first; + const auto bt_uid = device_to_switch->first; + const auto bt_adapter = device_to_switch->second; + + LOG4CXX_DEBUG(logger_, + "Known device with UID " + << bt_uid << " is appropriate for transport switching."); + + RaiseEvent( + &TransportManagerListener::OnDeviceSwitchingStart, bt_uid, usb_uid); + + bt_adapter->StopDevice(bt_uid); + adapter->DeviceSwitched(usb_uid); + + DeactivateDeviceConnections(bt_uid); + + device_to_reconnect_ = bt_uid; + + const uint32_t timeout = get_settings().app_transport_change_timer() + + get_settings().app_transport_change_timer_addition(); + device_switch_timer_.Start(timeout, timer::kSingleShot); + + LOG4CXX_DEBUG(logger_, + "Device switch for device id " << bt_uid << " is done."); + return; +} + +bool TransportManagerImpl::UpdateDeviceMapping( + transport_adapter::TransportAdapter* ta) { + const DeviceList adapter_device_list = ta->GetDeviceList(); + LOG4CXX_DEBUG(logger_, "DEVICE_LIST_UPDATED " << adapter_device_list.size()); + + sync_primitives::AutoWriteLock lock(device_to_adapter_map_lock_); + + LOG4CXX_DEBUG(logger_, + "Before cleanup and update. Device map size is " + << device_to_adapter_map_.size()); + + for (auto item = device_to_adapter_map_.begin(); + device_to_adapter_map_.end() != item;) { + const auto adapter = item->second; + if (adapter != ta) { + ++item; + continue; + } + + const auto device_uid = item->first; + if (adapter_device_list.end() != std::find(adapter_device_list.begin(), + adapter_device_list.end(), + device_uid)) { + ++item; + continue; + } + + device_to_adapter_map_.erase(item); + item = device_to_adapter_map_.begin(); + } + + LOG4CXX_DEBUG(logger_, + "After cleanup. Device map size is " + << device_to_adapter_map_.size()); + + for (DeviceList::const_iterator it = adapter_device_list.begin(); + it != adapter_device_list.end(); ++it) { - device_to_adapter_map_lock_.AcquireForWriting(); - device_to_adapter_map_.insert(std::make_pair(*it, ta)); - device_to_adapter_map_lock_.Release(); - DeviceHandle device_handle = converter_.UidToHandle(*it); - DeviceInfo info( - device_handle, *it, ta->DeviceName(*it), ta->GetConnectionType()); + const auto device_uid = *it; + const auto result = + device_to_adapter_map_.insert(std::make_pair(device_uid, ta)); + if (!result.second) { + LOG4CXX_WARN(logger_, + "Device UID " + << device_uid + << " is known already. Processing skipped." + "Connection type is: " << ta->GetConnectionType()); + continue; + } + DeviceHandle device_handle = + converter_.UidToHandle(device_uid, ta->GetConnectionType()); + DeviceInfo info(device_handle, + device_uid, + ta->DeviceName(device_uid), + ta->GetConnectionType()); RaiseEvent(&TransportManagerListener::OnDeviceFound, info); } + + LOG4CXX_DEBUG(logger_, + "After update. Device map size is " + << device_to_adapter_map_.size()); + + return true; +} + +void TransportManagerImpl::OnDeviceListUpdated(TransportAdapter* ta) { + LOG4CXX_TRACE(logger_, "enter. TransportAdapter: " << ta); + if (!UpdateDeviceMapping(ta)) { + LOG4CXX_ERROR(logger_, "Device list update failed."); + return; + } UpdateDeviceList(ta); std::vector<DeviceInfo> device_infos; device_list_lock_.AcquireForReading(); @@ -697,37 +916,43 @@ void TransportManagerImpl::OnDeviceListUpdated(TransportAdapter* ta) { device_infos.push_back(it->second); } device_list_lock_.Release(); + RaiseEvent(&TransportManagerListener::OnDeviceListUpdated, device_infos); LOG4CXX_TRACE(logger_, "exit"); } void TransportManagerImpl::Handle(TransportAdapterEvent event) { LOG4CXX_TRACE(logger_, "enter"); switch (event.event_type) { - case TransportAdapterListenerImpl::EventTypeEnum::ON_SEARCH_DONE: { + case EventTypeEnum::ON_SEARCH_DONE: { RaiseEvent(&TransportManagerListener::OnScanDevicesFinished); LOG4CXX_DEBUG(logger_, "event_type = ON_SEARCH_DONE"); break; } - case TransportAdapterListenerImpl::EventTypeEnum::ON_SEARCH_FAIL: { + case EventTypeEnum::ON_SEARCH_FAIL: { // error happened in real search process (external error) RaiseEvent(&TransportManagerListener::OnScanDevicesFailed, *static_cast<SearchDeviceError*>(event.event_error.get())); LOG4CXX_DEBUG(logger_, "event_type = ON_SEARCH_FAIL"); break; } - case TransportAdapterListenerImpl::EventTypeEnum::ON_DEVICE_LIST_UPDATED: { + case EventTypeEnum::ON_DEVICE_LIST_UPDATED: { OnDeviceListUpdated(event.transport_adapter); LOG4CXX_DEBUG(logger_, "event_type = ON_DEVICE_LIST_UPDATED"); break; } - case TransportAdapterListenerImpl::ON_FIND_NEW_APPLICATIONS_REQUEST: { + case EventTypeEnum::ON_TRANSPORT_SWITCH_REQUESTED: { + TryDeviceSwitch(event.transport_adapter); + LOG4CXX_DEBUG(logger_, "event_type = ON_TRANSPORT_SWITCH_REQUESTED"); + break; + } + case EventTypeEnum::ON_FIND_NEW_APPLICATIONS_REQUEST: { RaiseEvent(&TransportManagerListener::OnFindNewApplicationsRequest); LOG4CXX_DEBUG(logger_, "event_type = ON_FIND_NEW_APPLICATIONS_REQUEST"); break; } - case TransportAdapterListenerImpl::EventTypeEnum::ON_CONNECT_DONE: { - const DeviceHandle device_handle = - converter_.UidToHandle(event.device_uid); + case EventTypeEnum::ON_CONNECT_DONE: { + const DeviceHandle device_handle = converter_.UidToHandle( + event.device_uid, event.transport_adapter->GetConnectionType()); AddConnection(ConnectionInternal(this, event.transport_adapter, ++connection_id_counter_, @@ -744,10 +969,12 @@ void TransportManagerImpl::Handle(TransportAdapterEvent event) { LOG4CXX_DEBUG(logger_, "event_type = ON_CONNECT_DONE"); break; } - case TransportAdapterListenerImpl::EventTypeEnum::ON_CONNECT_FAIL: { + case EventTypeEnum::ON_CONNECT_FAIL: { RaiseEvent( &TransportManagerListener::OnConnectionFailed, - DeviceInfo(converter_.UidToHandle(event.device_uid), + DeviceInfo(converter_.UidToHandle( + event.device_uid, + event.transport_adapter->GetConnectionType()), event.device_uid, event.transport_adapter->DeviceName(event.device_uid), event.transport_adapter->GetConnectionType()), @@ -755,7 +982,7 @@ void TransportManagerImpl::Handle(TransportAdapterEvent event) { LOG4CXX_DEBUG(logger_, "event_type = ON_CONNECT_FAIL"); break; } - case TransportAdapterListenerImpl::EventTypeEnum::ON_DISCONNECT_DONE: { + case EventTypeEnum::ON_DISCONNECT_DONE: { connections_lock_.AcquireForReading(); ConnectionInternal* connection = GetConnection(event.device_uid, event.application_id); @@ -774,16 +1001,16 @@ void TransportManagerImpl::Handle(TransportAdapterEvent event) { LOG4CXX_DEBUG(logger_, "event_type = ON_DISCONNECT_DONE"); break; } - case TransportAdapterListenerImpl::EventTypeEnum::ON_DISCONNECT_FAIL: { - const DeviceHandle device_handle = - converter_.UidToHandle(event.device_uid); + case EventTypeEnum::ON_DISCONNECT_FAIL: { + const DeviceHandle device_handle = converter_.UidToHandle( + event.device_uid, event.transport_adapter->GetConnectionType()); RaiseEvent(&TransportManagerListener::OnDisconnectFailed, device_handle, DisconnectDeviceError()); LOG4CXX_DEBUG(logger_, "event_type = ON_DISCONNECT_FAIL"); break; } - case TransportAdapterListenerImpl::EventTypeEnum::ON_SEND_DONE: { + case EventTypeEnum::ON_SEND_DONE: { #ifdef TELEMETRY_MONITOR if (metric_observer_) { metric_observer_->StopRawMsg(event.event_data.get()); @@ -810,7 +1037,7 @@ void TransportManagerImpl::Handle(TransportAdapterEvent event) { LOG4CXX_DEBUG(logger_, "event_type = ON_SEND_DONE"); break; } - case TransportAdapterListenerImpl::EventTypeEnum::ON_SEND_FAIL: { + case EventTypeEnum::ON_SEND_FAIL: { #ifdef TELEMETRY_MONITOR if (metric_observer_) { metric_observer_->StopRawMsg(event.event_data.get()); @@ -845,11 +1072,11 @@ void TransportManagerImpl::Handle(TransportAdapterEvent event) { LOG4CXX_DEBUG(logger_, "eevent_type = ON_SEND_FAIL"); break; } - case TransportAdapterListenerImpl::EventTypeEnum::ON_RECEIVED_DONE: { + case EventTypeEnum::ON_RECEIVED_DONE: { { sync_primitives::AutoReadLock lock(connections_lock_); ConnectionInternal* connection = - GetConnection(event.device_uid, event.application_id); + GetActiveConnection(event.device_uid, event.application_id); if (connection == NULL) { LOG4CXX_ERROR(logger_, "Connection ('" << event.device_uid << ", " @@ -872,11 +1099,11 @@ void TransportManagerImpl::Handle(TransportAdapterEvent event) { LOG4CXX_DEBUG(logger_, "event_type = ON_RECEIVED_DONE"); break; } - case TransportAdapterListenerImpl::EventTypeEnum::ON_RECEIVED_FAIL: { + case EventTypeEnum::ON_RECEIVED_FAIL: { LOG4CXX_DEBUG(logger_, "Event ON_RECEIVED_FAIL"); connections_lock_.AcquireForReading(); ConnectionInternal* connection = - GetConnection(event.device_uid, event.application_id); + GetActiveConnection(event.device_uid, event.application_id); if (connection == NULL) { LOG4CXX_ERROR(logger_, "Connection ('" << event.device_uid << ", " @@ -891,12 +1118,11 @@ void TransportManagerImpl::Handle(TransportAdapterEvent event) { LOG4CXX_DEBUG(logger_, "event_type = ON_RECEIVED_FAIL"); break; } - case TransportAdapterListenerImpl::EventTypeEnum::ON_COMMUNICATION_ERROR: { + case EventTypeEnum::ON_COMMUNICATION_ERROR: { LOG4CXX_DEBUG(logger_, "event_type = ON_COMMUNICATION_ERROR"); break; } - case TransportAdapterListenerImpl::EventTypeEnum:: - ON_UNEXPECTED_DISCONNECT: { + case EventTypeEnum::ON_UNEXPECTED_DISCONNECT: { connections_lock_.AcquireForReading(); ConnectionInternal* connection = GetConnection(event.device_uid, event.application_id); @@ -983,7 +1209,8 @@ TransportManagerImpl::ConnectionInternal::ConnectionInternal( this, &ConnectionInternal::DisconnectFailedRoutine))) , shutdown_(false) , device_handle_(device_handle) - , messages_count(0) { + , messages_count(0) + , active_(true) { Connection::id = id; Connection::device = dev_id; Connection::application = app_id; @@ -999,4 +1226,55 @@ void TransportManagerImpl::ConnectionInternal::DisconnectFailedRoutine() { LOG4CXX_TRACE(logger_, "exit"); } +DeviceHandle TransportManagerImpl::Handle2GUIDConverter::UidToHandle( + const DeviceUID& dev_uid, const std::string& connection_type) { + DeviceHandle handle = hash_function_(dev_uid + connection_type); + + { + sync_primitives::AutoReadLock lock(conversion_table_lock_); + + auto it = std::find_if(conversion_table_.begin(), + conversion_table_.end(), + HandleFinder(handle)); + + if (it != conversion_table_.end()) { + LOG4CXX_DEBUG(logger_, + "Handle for UID is found: " << std::get<0>(*it) << "/" + << std::get<1>(*it) << "/" + << std::get<2>(*it)); + return std::get<2>(*it); + } + } + + sync_primitives::AutoWriteLock lock(conversion_table_lock_); + + auto t = std::make_tuple(dev_uid, connection_type, handle); + conversion_table_.push_back( + std::make_tuple(dev_uid, connection_type, handle)); + LOG4CXX_DEBUG(logger_, + "Handle for UID is added: " << std::get<0>(t) << "/" + << std::get<1>(t) << "/" + << std::get<2>(t)); + return handle; +} + +DeviceUID TransportManagerImpl::Handle2GUIDConverter::HandleToUid( + const DeviceHandle handle) { + sync_primitives::AutoReadLock lock(conversion_table_lock_); + + auto it = std::find_if( + conversion_table_.begin(), conversion_table_.end(), HandleFinder(handle)); + + if (it != conversion_table_.end()) { + LOG4CXX_DEBUG(logger_, + "Handle is found: " << std::get<0>(*it) << "/" + << std::get<1>(*it) << "/" + << std::get<2>(*it)); + return std::get<0>(*it); + } + + LOG4CXX_DEBUG(logger_, "Handle is not found: " << handle); + return DeviceUID("uknown_uid"); +} + } // namespace transport_manager 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 584add463d..e9ab2bae8e 100644 --- a/src/components/transport_manager/src/usb/libusb/usb_connection.cc +++ b/src/components/transport_manager/src/usb/libusb/usb_connection.cc @@ -43,6 +43,10 @@ #include "utils/logger.h" +// Define the buffer size, because the Android accessory protocol packet support +// packet buffers up to 16Kbytes +#define TRANSPORT_USB_BUFFER_MAX_SIZE (16 * 1024) + namespace transport_manager { namespace transport_adapter { @@ -64,6 +68,7 @@ UsbConnection::UsbConnection(const DeviceUID& device_uid, , out_endpoint_(0) , out_endpoint_max_packet_size_(0) , in_buffer_(NULL) + , in_buffer_size_(0) , in_transfer_(NULL) , out_transfer_(0) , out_messages_() @@ -96,7 +101,7 @@ bool UsbConnection::PostInTransfer() { device_handle_, in_endpoint_, in_buffer_, - in_endpoint_max_packet_size_, + in_buffer_size_, InTransferCallback, this, 0); @@ -307,7 +312,14 @@ bool UsbConnection::Init() { LOG4CXX_TRACE(logger_, "exit with FALSE. Condition: !FindEndpoints()"); return false; } - in_buffer_ = new unsigned char[in_endpoint_max_packet_size_]; + + if (in_endpoint_max_packet_size_ < TRANSPORT_USB_BUFFER_MAX_SIZE) { + in_buffer_size_ = TRANSPORT_USB_BUFFER_MAX_SIZE; + } else { + in_buffer_size_ = in_endpoint_max_packet_size_; + } + + in_buffer_ = new unsigned char[in_buffer_size_]; in_transfer_ = libusb_alloc_transfer(0); if (NULL == in_transfer_) { LOG4CXX_ERROR(logger_, "libusb_alloc_transfer failed"); diff --git a/src/components/transport_manager/src/usb/usb_aoa_adapter.cc b/src/components/transport_manager/src/usb/usb_aoa_adapter.cc index 3462b557ce..b7faf1ef6b 100644 --- a/src/components/transport_manager/src/usb/usb_aoa_adapter.cc +++ b/src/components/transport_manager/src/usb/usb_aoa_adapter.cc @@ -60,7 +60,7 @@ UsbAoaAdapter::UsbAoaAdapter(resumption::LastState& last_state, UsbAoaAdapter::~UsbAoaAdapter() {} DeviceType UsbAoaAdapter::GetDeviceType() const { - return PASA_AOA; + return AOA; } bool UsbAoaAdapter::IsInitialised() const { diff --git a/src/components/transport_manager/test/include/transport_manager/transport_adapter/mock_transport_adapter_impl.h b/src/components/transport_manager/test/include/transport_manager/transport_adapter/mock_transport_adapter_impl.h index 0636448e58..384f55605a 100644 --- a/src/components/transport_manager/test/include/transport_manager/transport_adapter/mock_transport_adapter_impl.h +++ b/src/components/transport_manager/test/include/transport_manager/transport_adapter/mock_transport_adapter_impl.h @@ -68,7 +68,7 @@ class MockTransportAdapterImpl : public TransportAdapterImpl { const ApplicationHandle& app_handle) { return this->FindEstablishedConnection(device_handle, app_handle); } - virtual ~MockTransportAdapterImpl(){}; + virtual ~MockTransportAdapterImpl() {} virtual DeviceType GetDeviceType() const { return DeviceType::UNKNOWN; @@ -76,6 +76,9 @@ class MockTransportAdapterImpl : public TransportAdapterImpl { MOCK_CONST_METHOD0(Store, void()); MOCK_METHOD0(Restore, bool()); + MOCK_CONST_METHOD1(FindDevice, + transport_manager::transport_adapter::DeviceSptr( + const DeviceUID& device_id)); }; } // namespace transport_manager_test diff --git a/src/components/transport_manager/test/include/transport_manager/transport_adapter/mock_transport_adapter_listener.h b/src/components/transport_manager/test/include/transport_manager/transport_adapter/mock_transport_adapter_listener.h index 8302a63beb..03e7630e8b 100644 --- a/src/components/transport_manager/test/include/transport_manager/transport_adapter/mock_transport_adapter_listener.h +++ b/src/components/transport_manager/test/include/transport_manager/transport_adapter/mock_transport_adapter_listener.h @@ -120,6 +120,8 @@ class MockTransportAdapterListener : public TransportAdapterListener { void(const TransportAdapter*, const DeviceUID&, const ApplicationHandle&)); + MOCK_METHOD1(OnTransportSwitchRequested, + void(const TransportAdapter* transport_adapter)); }; } // namespace transport_manager_test diff --git a/src/components/transport_manager/test/transport_adapter_listener_test.cc b/src/components/transport_manager/test/transport_adapter_listener_test.cc index c8e9af7d63..14b8850b49 100644 --- a/src/components/transport_manager/test/transport_adapter_listener_test.cc +++ b/src/components/transport_manager/test/transport_adapter_listener_test.cc @@ -45,16 +45,16 @@ using namespace ::transport_manager; class TransportAdapterListenerTest : public ::testing::Test { public: TransportAdapterListenerTest() - : app_handle(1) - , dev_id("device_id") - , transport_listener(&tr_mock, &adapter_mock) {} + : dev_id("device_id") + , transport_listener(&tr_mock, &adapter_mock) + , app_handle(1) {} protected: - const int app_handle; const std::string dev_id; MockTransportManager tr_mock; MockTransportAdapter adapter_mock; TransportAdapterListenerImpl transport_listener; + const int app_handle; }; MATCHER_P4(IsEvent, eventType, adapter, dev_id, app_id, "") { @@ -73,33 +73,30 @@ MATCHER_P5(IsEvent, eventType, adapter, dev_id, app_id, data, "") { TEST_F(TransportAdapterListenerTest, OnCommunicationError) { EXPECT_CALL( tr_mock, - ReceiveEventFromDevice(IsEvent( - TransportAdapterListenerImpl::EventTypeEnum::ON_COMMUNICATION_ERROR, - &adapter_mock, - dev_id, - app_handle))).WillOnce(Return(E_SUCCESS)); + ReceiveEventFromDevice(IsEvent(EventTypeEnum::ON_COMMUNICATION_ERROR, + &adapter_mock, + dev_id, + app_handle))).WillOnce(Return(E_SUCCESS)); transport_listener.OnCommunicationError(&adapter_mock, dev_id, app_handle); } TEST_F(TransportAdapterListenerTest, OnConnectDone) { - EXPECT_CALL(tr_mock, - ReceiveEventFromDevice(IsEvent( - TransportAdapterListenerImpl::EventTypeEnum::ON_CONNECT_DONE, - &adapter_mock, - dev_id, - app_handle))).WillOnce(Return(E_SUCCESS)); + EXPECT_CALL( + tr_mock, + ReceiveEventFromDevice(IsEvent( + EventTypeEnum::ON_CONNECT_DONE, &adapter_mock, dev_id, app_handle))) + .WillOnce(Return(E_SUCCESS)); transport_listener.OnConnectDone(&adapter_mock, dev_id, app_handle); } TEST_F(TransportAdapterListenerTest, OnConnectFailed) { ConnectError er; - EXPECT_CALL(tr_mock, - ReceiveEventFromDevice(IsEvent( - TransportAdapterListenerImpl::EventTypeEnum::ON_CONNECT_FAIL, - &adapter_mock, - dev_id, - app_handle))).WillOnce(Return(E_SUCCESS)); + EXPECT_CALL( + tr_mock, + ReceiveEventFromDevice(IsEvent( + EventTypeEnum::ON_CONNECT_FAIL, &adapter_mock, dev_id, app_handle))) + .WillOnce(Return(E_SUCCESS)); transport_listener.OnConnectFailed(&adapter_mock, dev_id, app_handle, er); } @@ -107,12 +104,12 @@ TEST_F(TransportAdapterListenerTest, OnDataReceiveDone) { ::protocol_handler::RawMessagePtr data_container; EXPECT_CALL(tr_mock, - ReceiveEventFromDevice(IsEvent( - TransportAdapterListenerImpl::EventTypeEnum::ON_RECEIVED_DONE, - &adapter_mock, - dev_id, - app_handle, - data_container))).WillOnce(Return(E_SUCCESS)); + ReceiveEventFromDevice(IsEvent(EventTypeEnum::ON_RECEIVED_DONE, + &adapter_mock, + dev_id, + app_handle, + data_container))) + .WillOnce(Return(E_SUCCESS)); transport_listener.OnDataReceiveDone( &adapter_mock, dev_id, app_handle, data_container); } @@ -120,12 +117,11 @@ TEST_F(TransportAdapterListenerTest, OnDataReceiveDone) { TEST_F(TransportAdapterListenerTest, OnDataReceiveFailed) { DataReceiveError err; - EXPECT_CALL(tr_mock, - ReceiveEventFromDevice(IsEvent( - TransportAdapterListenerImpl::EventTypeEnum::ON_RECEIVED_FAIL, - &adapter_mock, - dev_id, - app_handle))).WillOnce(Return(E_SUCCESS)); + EXPECT_CALL( + tr_mock, + ReceiveEventFromDevice(IsEvent( + EventTypeEnum::ON_RECEIVED_FAIL, &adapter_mock, dev_id, app_handle))) + .WillOnce(Return(E_SUCCESS)); transport_listener.OnDataReceiveFailed( &adapter_mock, dev_id, app_handle, err); } @@ -136,12 +132,12 @@ TEST_F(TransportAdapterListenerTest, OnDataSendDone) { new ::protocol_handler::RawMessage(1, 1, data, 3); EXPECT_CALL(tr_mock, - ReceiveEventFromDevice(IsEvent( - TransportAdapterListenerImpl::EventTypeEnum::ON_SEND_DONE, - &adapter_mock, - dev_id, - app_handle, - data_container))).WillOnce(Return(E_SUCCESS)); + ReceiveEventFromDevice(IsEvent(EventTypeEnum::ON_SEND_DONE, + &adapter_mock, + dev_id, + app_handle, + data_container))) + .WillOnce(Return(E_SUCCESS)); transport_listener.OnDataSendDone( &adapter_mock, dev_id, app_handle, data_container); } @@ -153,56 +149,50 @@ TEST_F(TransportAdapterListenerTest, OnDataSendFailed) { DataSendError err; EXPECT_CALL(tr_mock, - ReceiveEventFromDevice(IsEvent( - TransportAdapterListenerImpl::EventTypeEnum::ON_SEND_FAIL, - &adapter_mock, - dev_id, - app_handle, - data_container))).WillOnce(Return(E_SUCCESS)); + ReceiveEventFromDevice(IsEvent(EventTypeEnum::ON_SEND_FAIL, + &adapter_mock, + dev_id, + app_handle, + data_container))) + .WillOnce(Return(E_SUCCESS)); transport_listener.OnDataSendFailed( &adapter_mock, dev_id, app_handle, data_container, err); } TEST_F(TransportAdapterListenerTest, OnDeviceListUpdated) { - EXPECT_CALL( - tr_mock, - ReceiveEventFromDevice(IsEvent( - TransportAdapterListenerImpl::EventTypeEnum::ON_DEVICE_LIST_UPDATED, - &adapter_mock, - "", - 0))).WillOnce(Return(E_SUCCESS)); + EXPECT_CALL(tr_mock, + ReceiveEventFromDevice(IsEvent( + EventTypeEnum::ON_DEVICE_LIST_UPDATED, &adapter_mock, "", 0))) + .WillOnce(Return(E_SUCCESS)); transport_listener.OnDeviceListUpdated(&adapter_mock); } TEST_F(TransportAdapterListenerTest, OnDisconnectDeviceDone) { - EXPECT_CALL( - tr_mock, - ReceiveEventFromDevice(IsEvent( - TransportAdapterListenerImpl::EventTypeEnum::ON_DISCONNECT_DONE, - &adapter_mock, - dev_id, - app_handle))).WillOnce(Return(E_SUCCESS)); + EXPECT_CALL(tr_mock, + ReceiveEventFromDevice(IsEvent(EventTypeEnum::ON_DISCONNECT_DONE, + &adapter_mock, + dev_id, + app_handle))) + .WillOnce(Return(E_SUCCESS)); transport_listener.OnDisconnectDone(&adapter_mock, dev_id, app_handle); } TEST_F(TransportAdapterListenerTest, OnDisconnectFailed) { DisconnectError err; - EXPECT_CALL( - tr_mock, - ReceiveEventFromDevice(IsEvent( - TransportAdapterListenerImpl::EventTypeEnum::ON_DISCONNECT_FAIL, - &adapter_mock, - dev_id, - app_handle))).WillOnce(Return(E_SUCCESS)); + EXPECT_CALL(tr_mock, + ReceiveEventFromDevice(IsEvent(EventTypeEnum::ON_DISCONNECT_FAIL, + &adapter_mock, + dev_id, + app_handle))) + .WillOnce(Return(E_SUCCESS)); transport_listener.OnDisconnectFailed(&adapter_mock, dev_id, app_handle, err); } TEST_F(TransportAdapterListenerTest, OnFindNewApplicationsRequest) { EXPECT_CALL(tr_mock, ReceiveEventFromDevice( - IsEvent(TransportAdapterListenerImpl::EventTypeEnum:: - ON_FIND_NEW_APPLICATIONS_REQUEST, + IsEvent(EventTypeEnum::ON_FIND_NEW_APPLICATIONS_REQUEST, &adapter_mock, "", 0))).WillOnce(Return(E_SUCCESS)); @@ -211,11 +201,9 @@ TEST_F(TransportAdapterListenerTest, OnFindNewApplicationsRequest) { TEST_F(TransportAdapterListenerTest, OnSearchDeviceDone) { EXPECT_CALL(tr_mock, - ReceiveEventFromDevice(IsEvent( - TransportAdapterListenerImpl::EventTypeEnum::ON_SEARCH_DONE, - &adapter_mock, - "", - 0))).WillOnce(Return(E_SUCCESS)); + ReceiveEventFromDevice( + IsEvent(EventTypeEnum::ON_SEARCH_DONE, &adapter_mock, "", 0))) + .WillOnce(Return(E_SUCCESS)); transport_listener.OnSearchDeviceDone(&adapter_mock); } @@ -223,11 +211,9 @@ TEST_F(TransportAdapterListenerTest, OnSearchDeviceFailed) { SearchDeviceError er; EXPECT_CALL(tr_mock, - ReceiveEventFromDevice(IsEvent( - TransportAdapterListenerImpl::EventTypeEnum::ON_SEARCH_FAIL, - &adapter_mock, - "", - 0))).WillOnce(Return(E_SUCCESS)); + ReceiveEventFromDevice( + IsEvent(EventTypeEnum::ON_SEARCH_FAIL, &adapter_mock, "", 0))) + .WillOnce(Return(E_SUCCESS)); transport_listener.OnSearchDeviceFailed(&adapter_mock, er); } @@ -236,11 +222,10 @@ TEST_F(TransportAdapterListenerTest, OnUnexpectedDisconnect) { EXPECT_CALL( tr_mock, - ReceiveEventFromDevice(IsEvent( - TransportAdapterListenerImpl::EventTypeEnum::ON_UNEXPECTED_DISCONNECT, - &adapter_mock, - dev_id, - app_handle))).WillOnce(Return(E_SUCCESS)); + ReceiveEventFromDevice(IsEvent(EventTypeEnum::ON_UNEXPECTED_DISCONNECT, + &adapter_mock, + dev_id, + app_handle))).WillOnce(Return(E_SUCCESS)); transport_listener.OnUnexpectedDisconnect( &adapter_mock, dev_id, app_handle, err); } diff --git a/src/components/transport_manager/test/transport_adapter_test.cc b/src/components/transport_manager/test/transport_adapter_test.cc index 0c59e912ba..6d709e0c17 100644 --- a/src/components/transport_manager/test/transport_adapter_test.cc +++ b/src/components/transport_manager/test/transport_adapter_test.cc @@ -189,9 +189,10 @@ TEST_F(TransportAdapterTest, AddDevice) { MockTransportAdapterListener mock_listener; transport_adapter.AddListener(&mock_listener); - MockDevice* mockdev = new MockDevice(dev_id, uniq_id); + utils::SharedPtr<MockDevice> mockdev = + utils::MakeShared<MockDevice>(dev_id, uniq_id); - EXPECT_CALL(mock_listener, OnDeviceListUpdated(_)); + EXPECT_CALL(mock_listener, OnDeviceListUpdated(&transport_adapter)); transport_adapter.AddDevice(mockdev); } @@ -276,7 +277,8 @@ TEST_F(TransportAdapterTest, ConnectDevice_ServerNotAdded_DeviceAdded) { EXPECT_CALL(transport_adapter, Restore()).WillOnce(Return(true)); transport_adapter.Init(); - MockDevice* mockdev = new MockDevice(dev_id, uniq_id); + utils::SharedPtr<MockDevice> mockdev = + utils::MakeShared<MockDevice>(dev_id, uniq_id); transport_adapter.AddDevice(mockdev); std::vector<std::string> devList = transport_adapter.GetDeviceList(); @@ -286,6 +288,7 @@ TEST_F(TransportAdapterTest, ConnectDevice_ServerNotAdded_DeviceAdded) { int app_handle = 1; std::vector<int> intList = {app_handle}; EXPECT_CALL(*mockdev, GetApplicationList()).WillOnce(Return(intList)); + EXPECT_CALL(transport_adapter, FindDevice(uniq_id)).WillOnce(Return(mockdev)); TransportAdapter::Error res = transport_adapter.ConnectDevice(uniq_id); EXPECT_EQ(TransportAdapter::FAIL, res); @@ -303,6 +306,8 @@ TEST_F(TransportAdapterTest, ConnectDevice_DeviceNotAdded) { EXPECT_CALL(*serverMock, IsInitialised()).Times(0); EXPECT_CALL(*serverMock, CreateConnection(_, _)).Times(0); + EXPECT_CALL(transport_adapter, FindDevice(uniq_id)) + .WillOnce(Return(utils::SharedPtr<MockDevice>())); TransportAdapter::Error res = transport_adapter.ConnectDevice(uniq_id); EXPECT_EQ(TransportAdapter::BAD_PARAM, res); @@ -318,7 +323,8 @@ TEST_F(TransportAdapterTest, ConnectDevice_DeviceAdded) { EXPECT_CALL(transport_adapter, Restore()).WillOnce(Return(true)); transport_adapter.Init(); - MockDevice* mockdev = new MockDevice(dev_id, uniq_id); + utils::SharedPtr<MockDevice> mockdev = + utils::MakeShared<MockDevice>(dev_id, uniq_id); transport_adapter.AddDevice(mockdev); std::vector<std::string> devList = transport_adapter.GetDeviceList(); @@ -332,6 +338,7 @@ TEST_F(TransportAdapterTest, ConnectDevice_DeviceAdded) { EXPECT_CALL(*serverMock, IsInitialised()).WillOnce(Return(true)); EXPECT_CALL(*serverMock, CreateConnection(uniq_id, app_handle)) .WillOnce(Return(TransportAdapter::OK)); + EXPECT_CALL(transport_adapter, FindDevice(uniq_id)).WillOnce(Return(mockdev)); TransportAdapter::Error res = transport_adapter.ConnectDevice(uniq_id); EXPECT_EQ(TransportAdapter::OK, res); @@ -347,7 +354,8 @@ TEST_F(TransportAdapterTest, ConnectDevice_DeviceAddedTwice) { EXPECT_CALL(transport_adapter, Restore()).WillOnce(Return(true)); transport_adapter.Init(); - MockDevice* mockdev = new MockDevice(dev_id, uniq_id); + utils::SharedPtr<MockDevice> mockdev = + utils::MakeShared<MockDevice>(dev_id, uniq_id); transport_adapter.AddDevice(mockdev); std::vector<std::string> devList = transport_adapter.GetDeviceList(); @@ -361,6 +369,7 @@ TEST_F(TransportAdapterTest, ConnectDevice_DeviceAddedTwice) { EXPECT_CALL(*serverMock, IsInitialised()).WillOnce(Return(true)); EXPECT_CALL(*serverMock, CreateConnection(uniq_id, app_handle)) .WillOnce(Return(TransportAdapter::OK)); + EXPECT_CALL(transport_adapter, FindDevice(uniq_id)).WillOnce(Return(mockdev)); TransportAdapter::Error res = transport_adapter.ConnectDevice(uniq_id); EXPECT_EQ(TransportAdapter::OK, res); @@ -370,6 +379,7 @@ TEST_F(TransportAdapterTest, ConnectDevice_DeviceAddedTwice) { EXPECT_CALL(*serverMock, IsInitialised()).WillOnce(Return(true)); EXPECT_CALL(*serverMock, CreateConnection(uniq_id, app_handle)).Times(0); + EXPECT_CALL(transport_adapter, FindDevice(uniq_id)).WillOnce(Return(mockdev)); TransportAdapter::Error newres = transport_adapter.ConnectDevice(uniq_id); EXPECT_EQ(TransportAdapter::OK, newres); @@ -415,7 +425,8 @@ TEST_F(TransportAdapterTest, DisconnectDevice_DeviceAddedConnectionCreated) { EXPECT_CALL(transport_adapter, Restore()).WillOnce(Return(true)); transport_adapter.Init(); - MockDevice* mockdev = new MockDevice(dev_id, uniq_id); + utils::SharedPtr<MockDevice> mockdev = + utils::MakeShared<MockDevice>(dev_id, uniq_id); transport_adapter.AddDevice(mockdev); std::vector<std::string> devList = transport_adapter.GetDeviceList(); @@ -428,6 +439,7 @@ TEST_F(TransportAdapterTest, DisconnectDevice_DeviceAddedConnectionCreated) { EXPECT_CALL(*serverMock, IsInitialised()).WillOnce(Return(true)); EXPECT_CALL(*serverMock, CreateConnection(uniq_id, app_handle)) .WillOnce(Return(TransportAdapter::OK)); + EXPECT_CALL(transport_adapter, FindDevice(uniq_id)).WillOnce(Return(mockdev)); TransportAdapter::Error res = transport_adapter.ConnectDevice(uniq_id); EXPECT_EQ(TransportAdapter::OK, res); @@ -455,8 +467,9 @@ TEST_F(TransportAdapterTest, DeviceDisconnected) { MockTransportAdapterListener mock_listener; transport_adapter.AddListener(&mock_listener); - MockDevice* mockdev = new MockDevice(dev_id, uniq_id); - EXPECT_CALL(mock_listener, OnDeviceListUpdated(_)); + utils::SharedPtr<MockDevice> mockdev = + utils::MakeShared<MockDevice>(dev_id, uniq_id); + EXPECT_CALL(mock_listener, OnDeviceListUpdated(&transport_adapter)); transport_adapter.AddDevice(mockdev); std::vector<std::string> devList = transport_adapter.GetDeviceList(); @@ -465,23 +478,25 @@ TEST_F(TransportAdapterTest, DeviceDisconnected) { std::vector<int> intList = {app_handle}; EXPECT_CALL(*mockdev, GetApplicationList()).WillOnce(Return(intList)); - + EXPECT_CALL(transport_adapter, FindDevice(uniq_id)).WillOnce(Return(mockdev)); EXPECT_CALL(*serverMock, IsInitialised()).WillOnce(Return(true)); EXPECT_CALL(*serverMock, CreateConnection(uniq_id, app_handle)) .WillOnce(Return(TransportAdapter::OK)); TransportAdapter::Error res = transport_adapter.ConnectDevice(uniq_id); EXPECT_EQ(TransportAdapter::OK, res); - MockConnection* mock_connection = new MockConnection(); + utils::SharedPtr<MockConnection> mock_connection = + utils::MakeShared<MockConnection>(); transport_adapter.ConnectionCreated(mock_connection, uniq_id, app_handle); + EXPECT_CALL(mock_listener, OnDeviceListUpdated(&transport_adapter)); EXPECT_CALL(*mockdev, GetApplicationList()).WillOnce(Return(intList)); EXPECT_CALL( mock_listener, OnUnexpectedDisconnect(&transport_adapter, uniq_id, app_handle, _)); EXPECT_CALL(mock_listener, OnDisconnectDeviceDone(&transport_adapter, uniq_id)); - EXPECT_CALL(mock_listener, OnDeviceListUpdated(&transport_adapter)); + EXPECT_CALL(transport_adapter, FindDevice(uniq_id)).WillOnce(Return(mockdev)); DisconnectDeviceError error; transport_adapter.DeviceDisconnected(uniq_id, error); @@ -697,7 +712,8 @@ TEST_F(TransportAdapterTest, GetDeviceAndApplicationLists) { EXPECT_CALL(transport_adapter, Restore()).WillOnce(Return(true)); transport_adapter.Init(); - MockDevice* mockdev = new MockDevice(dev_id, uniq_id); + utils::SharedPtr<MockDevice> mockdev = + utils::MakeShared<MockDevice>(dev_id, uniq_id); transport_adapter.AddDevice(mockdev); std::vector<std::string> devList = transport_adapter.GetDeviceList(); @@ -707,6 +723,7 @@ TEST_F(TransportAdapterTest, GetDeviceAndApplicationLists) { int app_handle = 1; std::vector<int> intList = {app_handle}; EXPECT_CALL(*mockdev, GetApplicationList()).WillOnce(Return(intList)); + EXPECT_CALL(transport_adapter, FindDevice(uniq_id)).WillOnce(Return(mockdev)); std::vector<int> res = transport_adapter.GetApplicationList(uniq_id); ASSERT_EQ(1u, res.size()); EXPECT_EQ(intList[0], res[0]); @@ -752,6 +769,8 @@ TEST_F(TransportAdapterTest, RunAppOnDevice_NoDeviseWithAskedId_UNSUCCESS) { transport_adapter.AddDevice(mock_device); EXPECT_CALL(*mock_device, LaunchApp(bundle_id)).Times(0); + EXPECT_CALL(transport_adapter, FindDevice("test_device_uid1")) + .WillOnce(Return(utils::SharedPtr<MockDevice>())); transport_adapter.RunAppOnDevice("test_device_uid1", bundle_id); } @@ -769,10 +788,27 @@ TEST_F(TransportAdapterTest, RunAppOnDevice_DeviseWithAskedIdWasFound_SUCCESS) { transport_adapter.AddDevice(mock_device); EXPECT_CALL(*mock_device, LaunchApp(bundle_id)); + EXPECT_CALL(transport_adapter, FindDevice(device_uid)) + .WillOnce(Return(mock_device)); transport_adapter.RunAppOnDevice(device_uid, bundle_id); } +TEST_F(TransportAdapterTest, StopDevice) { + MockTransportAdapterImpl transport_adapter( + NULL, NULL, NULL, last_state_, transport_manager_settings); + EXPECT_CALL(transport_adapter, Restore()).WillOnce(Return(true)); + transport_adapter.Init(); + + auto mockdev = utils::MakeShared<MockDevice>(dev_id, uniq_id); + transport_adapter.AddDevice(mockdev); + + EXPECT_CALL(transport_adapter, FindDevice(uniq_id)).WillOnce(Return(mockdev)); + EXPECT_CALL(*mockdev, Stop()); + + transport_adapter.StopDevice(uniq_id); +} + } // namespace transport_manager_test } // namespace components } // namespace test diff --git a/src/components/transport_manager/test/transport_manager_impl_test.cc b/src/components/transport_manager/test/transport_manager_impl_test.cc index c7cf3b2cb2..eebb247908 100644 --- a/src/components/transport_manager/test/transport_manager_impl_test.cc +++ b/src/components/transport_manager/test/transport_manager_impl_test.cc @@ -70,10 +70,15 @@ const uint32_t kAsyncExpectationsTimeout = 10000u; class TransportManagerImplTest : public ::testing::Test { protected: TransportManagerImplTest() - : device_handle_(1) + : mock_adapter_(NULL) + , tm_(mock_transport_manager_settings_) , mac_address_("MA:CA:DR:ES:S") - , dev_info_(device_handle_, mac_address_, "TestDeviceName", "BTMAC") - , tm_(settings) {} + , connection_type_("BTMAC") + , device_name_("TestDeviceName") + , device_handle_( + tm_.get_converter().UidToHandle(mac_address_, connection_type_)) + , dev_info_( + device_handle_, mac_address_, device_name_, connection_type_) {} void SetUp() OVERRIDE { resumption::LastStateImpl last_state_("app_storage_folder", @@ -101,11 +106,46 @@ class TransportManagerImplTest : public ::testing::Test { MakeShared<RawMessage>(connection_key_, version_protocol_, data, kSize); } - void HandleDeviceListUpdated() { - const int type = static_cast<int>( - TransportAdapterListenerImpl::EventTypeEnum::ON_DEVICE_LIST_UPDATED); + DeviceInfo ConstructDeviceInfo(const std::string& mac_address, + const std::string& connection_type, + const std::string& device_name) { + const auto device_handle( + tm_.get_converter().UidToHandle(mac_address, connection_type)); + + return DeviceInfo(device_handle, mac_address, device_name, connection_type); + } + + void SetOnDeviceExpectations(const DeviceInfo& device_info) { + EXPECT_CALL(*tm_listener_, OnDeviceAdded(device_info)); + EXPECT_CALL(*tm_listener_, OnDeviceListUpdated(_)); + } + + void SetDeviceExpectations(MockTransportAdapter* mock_adapter, + const DeviceList& device_list, + const DeviceInfo& device_info) { + EXPECT_CALL(*mock_adapter, GetDeviceList()) + .WillRepeatedly(Return(device_list)); + + EXPECT_CALL(*mock_adapter, DeviceName(device_info.mac_address())) + .WillRepeatedly(Return(device_info.name())); + + EXPECT_CALL(*mock_adapter, GetConnectionType()) + .WillRepeatedly(Return(device_info.connection_type())); + } + + void SetAddDeviceExpectations(MockTransportAdapter* mock_adapter, + transport_adapter::DeviceType type, + const DeviceList& device_list, + const DeviceInfo& device_info) { + SetDeviceExpectations(mock_adapter, device_list, device_info); + + EXPECT_CALL(*mock_adapter, GetDeviceType()).WillRepeatedly(Return(type)); + + SetOnDeviceExpectations(device_info); + } - TransportAdapterEvent test_event(type, + void HandleDeviceListUpdated() { + TransportAdapterEvent test_event(EventTypeEnum::ON_DEVICE_LIST_UPDATED, mock_adapter_, dev_info_.mac_address(), application_id_, @@ -125,18 +165,15 @@ class TransportManagerImplTest : public ::testing::Test { .Times(AtLeast(1)) .WillRepeatedly(Return(dev_info_.connection_type())); - EXPECT_CALL(*tm_listener_, OnDeviceFound(dev_info_)); EXPECT_CALL(*tm_listener_, OnDeviceAdded(dev_info_)); + EXPECT_CALL(*tm_listener_, OnDeviceListUpdated(_)); tm_.TestHandle(test_event); device_list_.pop_back(); } void HandleConnection() { - const int type = static_cast<int>( - TransportAdapterListenerImpl::EventTypeEnum::ON_CONNECT_DONE); - - TransportAdapterEvent test_event(type, + TransportAdapterEvent test_event(EventTypeEnum::ON_CONNECT_DONE, mock_adapter_, dev_info_.mac_address(), application_id_, @@ -146,7 +183,7 @@ class TransportManagerImplTest : public ::testing::Test { EXPECT_CALL(*mock_adapter_, DeviceName(dev_info_.mac_address())) .WillOnce(Return(dev_info_.name())); EXPECT_CALL(*mock_adapter_, GetConnectionType()) - .WillOnce(Return(dev_info_.connection_type())); + .WillRepeatedly(Return(dev_info_.connection_type())); EXPECT_CALL(*tm_listener_, OnConnectionEstablished(dev_info_, connection_key_)); @@ -155,10 +192,7 @@ class TransportManagerImplTest : public ::testing::Test { } void HandleConnectionFailed() { - const int type = static_cast<int>( - TransportAdapterListenerImpl::EventTypeEnum::ON_CONNECT_FAIL); - - TransportAdapterEvent test_event(type, + TransportAdapterEvent test_event(EventTypeEnum::ON_CONNECT_FAIL, mock_adapter_, dev_info_.mac_address(), application_id_, @@ -168,7 +202,7 @@ class TransportManagerImplTest : public ::testing::Test { EXPECT_CALL(*mock_adapter_, DeviceName(dev_info_.mac_address())) .WillOnce(Return(dev_info_.name())); EXPECT_CALL(*mock_adapter_, GetConnectionType()) - .WillOnce(Return(dev_info_.connection_type())); + .WillRepeatedly(Return(dev_info_.connection_type())); EXPECT_CALL(*tm_listener_, OnConnectionFailed(dev_info_, _)); @@ -176,9 +210,7 @@ class TransportManagerImplTest : public ::testing::Test { } void HandleSendDone() { - const int type = static_cast<int>( - TransportAdapterListenerImpl::EventTypeEnum::ON_SEND_DONE); - TransportAdapterEvent test_event(type, + TransportAdapterEvent test_event(EventTypeEnum::ON_SEND_DONE, mock_adapter_, mac_address_, application_id_, @@ -193,9 +225,7 @@ class TransportManagerImplTest : public ::testing::Test { } void HandleReceiveDone() { - const int type = static_cast<int>( - TransportAdapterListenerImpl::EventTypeEnum::ON_RECEIVED_DONE); - TransportAdapterEvent test_event(type, + TransportAdapterEvent test_event(EventTypeEnum::ON_RECEIVED_DONE, mock_adapter_, mac_address_, application_id_, @@ -210,10 +240,7 @@ class TransportManagerImplTest : public ::testing::Test { } void HandleSendFailed() { - const int type = static_cast<int>( - TransportAdapterListenerImpl::EventTypeEnum::ON_SEND_FAIL); - - TransportAdapterEvent test_event(type, + TransportAdapterEvent test_event(EventTypeEnum::ON_SEND_FAIL, mock_adapter_, mac_address_, application_id_, @@ -226,10 +253,7 @@ class TransportManagerImplTest : public ::testing::Test { } void HandleSearchDone() { - const int type = static_cast<int>( - TransportAdapterListenerImpl::EventTypeEnum::ON_SEARCH_DONE); - - TransportAdapterEvent test_event(type, + TransportAdapterEvent test_event(EventTypeEnum::ON_SEARCH_DONE, mock_adapter_, mac_address_, application_id_, @@ -242,10 +266,7 @@ class TransportManagerImplTest : public ::testing::Test { } void HandleSearchFail() { - const int type = static_cast<int>( - TransportAdapterListenerImpl::EventTypeEnum::ON_SEARCH_FAIL); - - TransportAdapterEvent test_event(type, + TransportAdapterEvent test_event(EventTypeEnum::ON_SEARCH_FAIL, mock_adapter_, mac_address_, application_id_, @@ -258,16 +279,13 @@ class TransportManagerImplTest : public ::testing::Test { } void HandleFindNewApplicationsRequest() { - const int type = - static_cast<int>(TransportAdapterListenerImpl::EventTypeEnum:: - ON_FIND_NEW_APPLICATIONS_REQUEST); - - TransportAdapterEvent test_event(type, - mock_adapter_, - mac_address_, - application_id_, - test_message_, - error_); + TransportAdapterEvent test_event( + EventTypeEnum::ON_FIND_NEW_APPLICATIONS_REQUEST, + mock_adapter_, + mac_address_, + application_id_, + test_message_, + error_); EXPECT_CALL(*tm_listener_, OnFindNewApplicationsRequest()); @@ -275,10 +293,7 @@ class TransportManagerImplTest : public ::testing::Test { } void HandleConnectionClosed() { - const int type = static_cast<int>( - TransportAdapterListenerImpl::EventTypeEnum::ON_DISCONNECT_DONE); - - TransportAdapterEvent test_event(type, + TransportAdapterEvent test_event(EventTypeEnum::ON_DISCONNECT_DONE, mock_adapter_, mac_address_, application_id_, @@ -293,10 +308,7 @@ class TransportManagerImplTest : public ::testing::Test { } void HandleDisconnectionFailed() { - const int type = static_cast<int>( - TransportAdapterListenerImpl::EventTypeEnum::ON_DISCONNECT_FAIL); - - TransportAdapterEvent test_event(type, + TransportAdapterEvent test_event(EventTypeEnum::ON_DISCONNECT_FAIL, mock_adapter_, mac_address_, application_id_, @@ -312,23 +324,26 @@ class TransportManagerImplTest : public ::testing::Test { EXPECT_CALL(*mock_adapter_, Terminate()); ASSERT_EQ(E_SUCCESS, tm_.Stop()); } - MockTransportManagerSettings settings; + + MockTransportManagerSettings mock_transport_manager_settings_; #ifdef TELEMETRY_MONITOR MockTMTelemetryObserver mock_metric_observer_; #endif // TELEMETRY_MONITOR MockTransportAdapter* mock_adapter_; utils::SharedPtr<MockTransportManagerListener> tm_listener_; + MockTransportManagerImpl tm_; const ApplicationHandle application_id_ = 1; ConnectionUID connection_key_; RawMessagePtr test_message_; - DeviceHandle device_handle_; std::string mac_address_; + std::string connection_type_; + std::string device_name_; + DeviceHandle device_handle_; const DeviceInfo dev_info_; DeviceList device_list_; BaseErrorPtr error_; - MockTransportManagerImpl tm_; }; TEST_F(TransportManagerImplTest, SearchDevices_AdaptersNotAdded) { @@ -642,45 +657,39 @@ TEST_F(TransportManagerImplTest, Reinit_InitAdapterFailed) { TEST_F(TransportManagerImplTest, UpdateDeviceList_AddNewDevice) { device_list_.push_back(dev_info_.mac_address()); - EXPECT_CALL(*mock_adapter_, GetDeviceList()).WillOnce(Return(device_list_)); - EXPECT_CALL(*mock_adapter_, DeviceName(dev_info_.mac_address())) - .WillOnce(Return(dev_info_.name())); - EXPECT_CALL(*mock_adapter_, GetConnectionType()) - .WillOnce(Return(dev_info_.connection_type())); - EXPECT_CALL(*tm_listener_, OnDeviceAdded(dev_info_)); - - tm_.UpdateDeviceList(mock_adapter_); + SetDeviceExpectations(mock_adapter_, device_list_, dev_info_); + EXPECT_CALL(*tm_listener_, OnDeviceFound(dev_info_)); + SetOnDeviceExpectations(dev_info_); + tm_.OnDeviceListUpdated(mock_adapter_); device_list_.pop_back(); } TEST_F(TransportManagerImplTest, UpdateDeviceList_RemoveDevice) { device_list_.push_back(dev_info_.mac_address()); - - ::testing::InSequence seq; - EXPECT_CALL(*mock_adapter_, GetDeviceList()).WillOnce(Return(device_list_)); - EXPECT_CALL(*mock_adapter_, GetConnectionType()) - .WillOnce(Return(dev_info_.connection_type())); - EXPECT_CALL(*mock_adapter_, DeviceName(dev_info_.mac_address())) - .WillOnce(Return(dev_info_.name())); - EXPECT_CALL(*tm_listener_, OnDeviceAdded(dev_info_)); - tm_.UpdateDeviceList(mock_adapter_); + { + SetDeviceExpectations(mock_adapter_, device_list_, dev_info_); + ::testing::InSequence s; + EXPECT_CALL(*tm_listener_, OnDeviceFound(dev_info_)); + SetOnDeviceExpectations(dev_info_); + tm_.OnDeviceListUpdated(mock_adapter_); + } device_list_.pop_back(); + SetDeviceExpectations(mock_adapter_, device_list_, dev_info_); + // Device list is empty now - EXPECT_CALL(*mock_adapter_, GetDeviceList()).WillOnce(Return(device_list_)); + ::testing::InSequence s; EXPECT_CALL(*tm_listener_, OnDeviceRemoved(dev_info_)); - tm_.UpdateDeviceList(mock_adapter_); + EXPECT_CALL(*tm_listener_, OnDeviceListUpdated(_)); + tm_.OnDeviceListUpdated(mock_adapter_); } /* * Tests which check correct handling and receiving events */ TEST_F(TransportManagerImplTest, ReceiveEventFromDevice_OnSearchDeviceDone) { - const int type = static_cast<int>( - TransportAdapterListenerImpl::EventTypeEnum::ON_SEARCH_DONE); - TestAsyncWaiter waiter; - TransportAdapterEvent test_event(type, + TransportAdapterEvent test_event(EventTypeEnum::ON_SEARCH_DONE, mock_adapter_, mac_address_, application_id_, @@ -696,11 +705,8 @@ TEST_F(TransportManagerImplTest, ReceiveEventFromDevice_OnSearchDeviceDone) { } TEST_F(TransportManagerImplTest, ReceiveEventFromDevice_OnSearchDeviceFail) { - const int type = static_cast<int>( - TransportAdapterListenerImpl::EventTypeEnum::ON_SEARCH_FAIL); - TestAsyncWaiter waiter; - TransportAdapterEvent test_event(type, + TransportAdapterEvent test_event(EventTypeEnum::ON_SEARCH_FAIL, mock_adapter_, mac_address_, application_id_, @@ -716,10 +722,7 @@ TEST_F(TransportManagerImplTest, ReceiveEventFromDevice_OnSearchDeviceFail) { } TEST_F(TransportManagerImplTest, ReceiveEventFromDevice_DeviceListUpdated) { - const int type = static_cast<int>( - TransportAdapterListenerImpl::EventTypeEnum::ON_DEVICE_LIST_UPDATED); - - TransportAdapterEvent test_event(type, + TransportAdapterEvent test_event(EventTypeEnum::ON_DEVICE_LIST_UPDATED, mock_adapter_, dev_info_.mac_address(), application_id_, @@ -772,10 +775,7 @@ TEST_F(TransportManagerImplTest, CheckReceiveEvent) { TEST_F(TransportManagerImplTest, CheckReceiveFailedEvent) { // Arrange - const int type = static_cast<int>( - TransportAdapterListenerImpl::EventTypeEnum::ON_RECEIVED_FAIL); - - TransportAdapterEvent test_event(type, + TransportAdapterEvent test_event(EventTypeEnum::ON_RECEIVED_FAIL, mock_adapter_, mac_address_, application_id_, @@ -790,10 +790,7 @@ TEST_F(TransportManagerImplTest, CheckReceiveFailedEvent) { TEST_F(TransportManagerImplTest, CheckUnexpectedDisconnect) { // Arrange - const int type = static_cast<int>( - TransportAdapterListenerImpl::EventTypeEnum::ON_UNEXPECTED_DISCONNECT); - - TransportAdapterEvent test_event(type, + TransportAdapterEvent test_event(EventTypeEnum::ON_UNEXPECTED_DISCONNECT, mock_adapter_, mac_address_, application_id_, @@ -875,10 +872,12 @@ TEST_F(TransportManagerImplTest, SendMessageToDevice_ConnectionNotExist) { TEST_F(TransportManagerImplTest, ReceiveEventFromDevice_TMIsNotInitialized) { // Arrange - const int type = static_cast<int>( - TransportAdapterListenerImpl::EventTypeEnum::ON_SEARCH_DONE); - TransportAdapterEvent test_event( - type, NULL, mac_address_, application_id_, test_message_, error_); + TransportAdapterEvent test_event(EventTypeEnum::ON_SEARCH_DONE, + NULL, + mac_address_, + application_id_, + test_message_, + error_); // Check before Act UninitializeTM(); // Act and Assert @@ -938,84 +937,10 @@ TEST_F(TransportManagerImplTest, } TEST_F(TransportManagerImplTest, - UpdateDeviceList_AddDevices_TwoTransportAdapters) { - // Arrange - MockTransportAdapter* second_mock_adapter = new MockTransportAdapter(); - device_list_.push_back(dev_info_.mac_address()); - // Check before Act - EXPECT_CALL(*second_mock_adapter, AddListener(_)); - EXPECT_CALL(*second_mock_adapter, IsInitialised()).WillOnce(Return(true)); - EXPECT_EQ(E_SUCCESS, tm_.AddTransportAdapter(second_mock_adapter)); - - // Act and Assert - EXPECT_CALL(*second_mock_adapter, GetDeviceList()) - .WillOnce(Return(device_list_)); - EXPECT_CALL(*second_mock_adapter, DeviceName(dev_info_.mac_address())) - .WillOnce(Return(dev_info_.name())); - EXPECT_CALL(*second_mock_adapter, GetConnectionType()) - .WillOnce(Return(dev_info_.connection_type())); - EXPECT_CALL(*tm_listener_, OnDeviceAdded(dev_info_)); - tm_.UpdateDeviceList(second_mock_adapter); - - EXPECT_CALL(*mock_adapter_, GetDeviceList()).WillOnce(Return(device_list_)); - EXPECT_CALL(*mock_adapter_, DeviceName(dev_info_.mac_address())) - .WillOnce(Return(dev_info_.name())); - EXPECT_CALL(*mock_adapter_, GetConnectionType()) - .WillOnce(Return(dev_info_.connection_type())); - EXPECT_CALL(*tm_listener_, OnDeviceAdded(dev_info_)); - tm_.UpdateDeviceList(mock_adapter_); - - device_list_.pop_back(); -} - -TEST_F(TransportManagerImplTest, - UpdateDeviceList_RemoveDevices_TwoTransportAdapters) { - // Arrange - MockTransportAdapter* second_mock_adapter = new MockTransportAdapter(); - device_list_.push_back(dev_info_.mac_address()); - // Check before Act - EXPECT_CALL(*second_mock_adapter, AddListener(_)); - EXPECT_CALL(*second_mock_adapter, IsInitialised()).WillOnce(Return(true)); - EXPECT_EQ(E_SUCCESS, tm_.AddTransportAdapter(second_mock_adapter)); - - // Act and Assert - EXPECT_CALL(*second_mock_adapter, GetDeviceList()) - .WillOnce(Return(device_list_)); - EXPECT_CALL(*second_mock_adapter, DeviceName(dev_info_.mac_address())) - .WillOnce(Return(dev_info_.name())); - EXPECT_CALL(*second_mock_adapter, GetConnectionType()) - .WillOnce(Return(dev_info_.connection_type())); - EXPECT_CALL(*tm_listener_, OnDeviceAdded(dev_info_)); - tm_.UpdateDeviceList(second_mock_adapter); - - EXPECT_CALL(*mock_adapter_, GetDeviceList()).WillOnce(Return(device_list_)); - EXPECT_CALL(*mock_adapter_, DeviceName(dev_info_.mac_address())) - .WillOnce(Return(dev_info_.name())); - EXPECT_CALL(*mock_adapter_, GetConnectionType()) - .WillOnce(Return(dev_info_.connection_type())); - EXPECT_CALL(*tm_listener_, OnDeviceAdded(dev_info_)); - tm_.UpdateDeviceList(mock_adapter_); - - device_list_.pop_back(); - - EXPECT_CALL(*second_mock_adapter, GetDeviceList()) - .WillOnce(Return(device_list_)); - EXPECT_CALL(*tm_listener_, OnDeviceRemoved(dev_info_)); - tm_.UpdateDeviceList(second_mock_adapter); - - EXPECT_CALL(*mock_adapter_, GetDeviceList()).WillOnce(Return(device_list_)); - EXPECT_CALL(*tm_listener_, OnDeviceRemoved(dev_info_)); - tm_.UpdateDeviceList(mock_adapter_); -} - -TEST_F(TransportManagerImplTest, CheckEventOnDisconnectDone_ConnectionNotExist) { // SetUp does not add connections // Arrange - const int type = static_cast<int>( - TransportAdapterListenerImpl::EventTypeEnum::ON_DISCONNECT_DONE); - - TransportAdapterEvent test_event(type, + TransportAdapterEvent test_event(EventTypeEnum::ON_DISCONNECT_DONE, mock_adapter_, mac_address_, application_id_, @@ -1031,10 +956,7 @@ TEST_F(TransportManagerImplTest, TEST_F(TransportManagerImplTest, CheckEventOnSendDone_ConnectionNotExist) { // SetUp does not add connections // Arrange - const int type = static_cast<int>( - TransportAdapterListenerImpl::EventTypeEnum::ON_SEND_DONE); - - TransportAdapterEvent test_event(type, + TransportAdapterEvent test_event(EventTypeEnum::ON_SEND_DONE, mock_adapter_, mac_address_, application_id_, @@ -1052,9 +974,7 @@ TEST_F(TransportManagerImplTest, CheckEventOnSendDone_ConnectionNotExist) { TEST_F(TransportManagerImplTest, CheckEventOnReceivedDone_ConnectionNotExist) { // SetUp does not add connections // Arrange - const int type = static_cast<int>( - TransportAdapterListenerImpl::EventTypeEnum::ON_RECEIVED_DONE); - TransportAdapterEvent test_event(type, + TransportAdapterEvent test_event(EventTypeEnum::ON_RECEIVED_DONE, mock_adapter_, mac_address_, application_id_, @@ -1071,9 +991,7 @@ TEST_F(TransportManagerImplTest, CheckEventOnReceivedDone_ConnectionNotExist) { TEST_F(TransportManagerImplTest, CheckEventOnReceivedFail_ConnectionNotExist) { // SetUp does not add connections // Arrange - const int type = static_cast<int>( - TransportAdapterListenerImpl::EventTypeEnum::ON_RECEIVED_FAIL); - TransportAdapterEvent test_event(type, + TransportAdapterEvent test_event(EventTypeEnum::ON_RECEIVED_FAIL, mock_adapter_, mac_address_, application_id_, @@ -1088,9 +1006,7 @@ TEST_F(TransportManagerImplTest, CheckEventOnUnexpectedDisconnect_ConnectionNotExist) { // SetUp does not add connections // Arrange - const int type = static_cast<int>( - TransportAdapterListenerImpl::EventTypeEnum::ON_UNEXPECTED_DISCONNECT); - TransportAdapterEvent test_event(type, + TransportAdapterEvent test_event(EventTypeEnum::ON_UNEXPECTED_DISCONNECT, mock_adapter_, mac_address_, application_id_, @@ -1108,6 +1024,305 @@ TEST_F(TransportManagerImplTest, RunAppOnDevice_TransportAdapterFound_SUCCESS) { tm_.RunAppOnDevice(device_handle_, bundle_id); } +TEST_F(TransportManagerImplTest, + UpdateDeviceList_AddDevices_TwoTransportAdapters_ExpectSuccess) { + // Arrange + MockTransportAdapter* second_mock_adapter = new MockTransportAdapter(); + device_list_.push_back(dev_info_.mac_address()); + // Check before Act + EXPECT_CALL(*second_mock_adapter, AddListener(_)); + EXPECT_CALL(*second_mock_adapter, IsInitialised()).WillOnce(Return(true)); + EXPECT_EQ(E_SUCCESS, tm_.AddTransportAdapter(second_mock_adapter)); + + // Act and Assert + SetDeviceExpectations(mock_adapter_, device_list_, dev_info_); + EXPECT_CALL(*tm_listener_, OnDeviceFound(dev_info_)); + SetOnDeviceExpectations(dev_info_); + tm_.OnDeviceListUpdated(mock_adapter_); + + const std::string mac_address("NE:WA:DR:ES:SS"); + const std::string connection_type("TCP"); + const std::string device_name("TestName"); + const transport_manager::DeviceHandle device_handle( + tm_.get_converter().UidToHandle(mac_address, connection_type)); + + DeviceInfo second_device( + device_handle, mac_address, device_name, connection_type); + DeviceList device_list_2; + device_list_2.push_back(second_device.mac_address()); + + SetDeviceExpectations(second_mock_adapter, device_list_2, second_device); + + EXPECT_CALL(*tm_listener_, OnDeviceFound(second_device)); + SetOnDeviceExpectations(second_device); + tm_.OnDeviceListUpdated(second_mock_adapter); + + device_list_.pop_back(); +} + +TEST_F( + TransportManagerImplTest, + UpdateDeviceList_AddSameUUIDNonSwitchableDevices_TwoTransportAdapters_ExpectNoSwitch) { + device_list_.push_back(dev_info_.mac_address()); + SetAddDeviceExpectations(mock_adapter_, + transport_adapter::DeviceType::TCP, + device_list_, + dev_info_); + + tm_.OnDeviceListUpdated(mock_adapter_); + + // Adapter will be removed by TM on destruction + MockTransportAdapter* second_mock_adapter = new MockTransportAdapter(); + EXPECT_CALL(*second_mock_adapter, AddListener(_)); + EXPECT_CALL(*second_mock_adapter, IsInitialised()).WillOnce(Return(true)); + EXPECT_EQ(E_SUCCESS, tm_.AddTransportAdapter(second_mock_adapter)); + + const auto usb_serial = "USB_serial"; + DeviceInfo second_device = + ConstructDeviceInfo(usb_serial, "USB_IOS", "SecondDeviceName"); + + DeviceList second_adapter_device_list; + second_adapter_device_list.push_back(usb_serial); + + SetAddDeviceExpectations(second_mock_adapter, + transport_adapter::DeviceType::IOS_USB, + second_adapter_device_list, + second_device); + + tm_.OnDeviceListUpdated(second_mock_adapter); + + // Act + EXPECT_CALL(*second_mock_adapter, StopDevice(_)).Times(0); + EXPECT_CALL(*second_mock_adapter, DeviceSwitched(_)).Times(0); + + tm_.TestHandle( + TransportAdapterEvent(EventTypeEnum::ON_TRANSPORT_SWITCH_REQUESTED, + second_mock_adapter, + mac_address_, + application_id_, + test_message_, + error_)); + + device_list_.pop_back(); +} + +TEST_F(TransportManagerImplTest, OnlyOneDeviceShouldNotTriggerSwitch) { + device_list_.push_back(dev_info_.mac_address()); + SetDeviceExpectations(mock_adapter_, device_list_, dev_info_); + SetOnDeviceExpectations(dev_info_); + + EXPECT_CALL(*mock_adapter_, StopDevice(_)).Times(0); + EXPECT_CALL(*mock_adapter_, DeviceSwitched(_)).Times(0); + EXPECT_CALL(*tm_listener_, OnDeviceSwitchingStart(_, _)).Times(0); + + tm_.TestHandle(TransportAdapterEvent(EventTypeEnum::ON_DEVICE_LIST_UPDATED, + mock_adapter_, + mac_address_, + application_id_, + test_message_, + error_)); + + device_list_.pop_back(); +} + +TEST_F(TransportManagerImplTest, + TwoTransportAdapterAddSameSwitchableDevice_ExpectSuccess) { + device_list_.push_back(dev_info_.mac_address()); + const uint32_t timeout = 0; + + SetAddDeviceExpectations(mock_adapter_, + transport_adapter::DeviceType::IOS_BT, + device_list_, + dev_info_); + + EXPECT_CALL(*tm_listener_, OnDeviceFound(dev_info_)); + + tm_.TestHandle(TransportAdapterEvent(EventTypeEnum::ON_DEVICE_LIST_UPDATED, + mock_adapter_, + mac_address_, + application_id_, + test_message_, + error_)); + + auto second_mock_adapter = utils::MakeShared<MockTransportAdapter>(); + + const auto usb_serial = "USB_serial"; + DeviceInfo second_device = + ConstructDeviceInfo(usb_serial, "USB_IOS", "SecondDeviceName"); + + DeviceList second_adapter_devices; + second_adapter_devices.push_back(second_device.mac_address()); + + SetAddDeviceExpectations(second_mock_adapter.get(), + transport_adapter::DeviceType::IOS_USB, + second_adapter_devices, + second_device); + + EXPECT_CALL(*tm_listener_, OnDeviceFound(second_device)); + EXPECT_CALL(*second_mock_adapter, DeviceSwitched(_)).Times(0); + + tm_.TestHandle(TransportAdapterEvent(EventTypeEnum::ON_DEVICE_LIST_UPDATED, + second_mock_adapter.get(), + mac_address_, + application_id_, + test_message_, + error_)); + + // Act + const auto uuid = "ABC-DEF-GHJ-KLM"; + SwitchableDevices bt_switchables; + bt_switchables.insert(std::make_pair(dev_info_.mac_address(), uuid)); + EXPECT_CALL(*mock_adapter_, GetSwitchableDevices()) + .WillOnce(Return(bt_switchables)); + + SwitchableDevices usb_switchables; + usb_switchables.insert(std::make_pair(second_device.mac_address(), uuid)); + EXPECT_CALL(*second_mock_adapter, GetSwitchableDevices()) + .WillOnce(Return(usb_switchables)); + + EXPECT_CALL(*mock_adapter_, StopDevice(mac_address_)); + EXPECT_CALL(*second_mock_adapter, DeviceSwitched(usb_serial)); + EXPECT_CALL(mock_transport_manager_settings_, app_transport_change_timer()) + .WillOnce(Return(timeout)); + EXPECT_CALL(mock_transport_manager_settings_, + app_transport_change_timer_addition()).WillOnce(Return(0)); + + EXPECT_CALL(*tm_listener_, OnDeviceSwitchingStart(mac_address_, usb_serial)); + + tm_.TestHandle( + TransportAdapterEvent(EventTypeEnum::ON_TRANSPORT_SWITCH_REQUESTED, + second_mock_adapter.get(), + mac_address_, + application_id_, + test_message_, + error_)); + + // There is internal timer started on switching. Need to wait for timeout. + sleep(1); + device_list_.pop_back(); +} + +TEST_F(TransportManagerImplTest, + TwoTransportAdapterAddSameDeviceSecondSkipped) { + device_list_.push_back(dev_info_.mac_address()); + + SetAddDeviceExpectations(mock_adapter_, + transport_adapter::DeviceType::IOS_BT, + device_list_, + dev_info_); + + EXPECT_CALL(*tm_listener_, OnDeviceFound(_)); + + tm_.TestHandle(TransportAdapterEvent(EventTypeEnum::ON_DEVICE_LIST_UPDATED, + mock_adapter_, + mac_address_, + application_id_, + test_message_, + error_)); + + auto second_mock_adapter = utils::MakeShared<MockTransportAdapter>(); + + DeviceInfo second_device = + ConstructDeviceInfo("MA:CA:DR:ES:S", "USB_IOS", "SecondDeviceName"); + + SetAddDeviceExpectations(second_mock_adapter.get(), + transport_adapter::DeviceType::IOS_USB, + device_list_, + second_device); + + EXPECT_CALL(*tm_listener_, OnDeviceFound(_)).Times(0); + + tm_.TestHandle(TransportAdapterEvent(EventTypeEnum::ON_DEVICE_LIST_UPDATED, + second_mock_adapter.get(), + mac_address_, + application_id_, + test_message_, + error_)); + + device_list_.pop_back(); +} + +TEST_F(TransportManagerImplTest, NoDeviceTransportSwitchRequest_Fail) { + device_list_.push_back(dev_info_.mac_address()); + SetAddDeviceExpectations(mock_adapter_, + transport_adapter::DeviceType::IOS_USB, + device_list_, + dev_info_); + + EXPECT_CALL(*tm_listener_, OnDeviceFound(_)); + + tm_.TestHandle(TransportAdapterEvent(EventTypeEnum::ON_DEVICE_LIST_UPDATED, + mock_adapter_, + mac_address_, + application_id_, + test_message_, + error_)); + + EXPECT_CALL(*mock_adapter_, StopDevice(mac_address_)).Times(0); + + EXPECT_CALL(*tm_listener_, OnDeviceSwitchingStart(mac_address_, mac_address_)) + .Times(0); + + tm_.TestHandle( + TransportAdapterEvent(EventTypeEnum::ON_TRANSPORT_SWITCH_REQUESTED, + mock_adapter_, + mac_address_, + application_id_, + test_message_, + error_)); + + device_list_.pop_back(); +} + +TEST_F(TransportManagerImplTest, + UpdateDeviceList_RemoveDevices_TwoTransportAdapters_ExpectSuccess) { + // Arrange + MockTransportAdapter* second_mock_adapter = new MockTransportAdapter(); + device_list_.push_back(dev_info_.mac_address()); + // Check before Act + EXPECT_CALL(*second_mock_adapter, AddListener(_)); + EXPECT_CALL(*second_mock_adapter, IsInitialised()).WillOnce(Return(true)); + EXPECT_EQ(E_SUCCESS, tm_.AddTransportAdapter(second_mock_adapter)); + + // Act and Assert + SetDeviceExpectations(mock_adapter_, device_list_, dev_info_); + + EXPECT_CALL(*tm_listener_, OnDeviceFound(dev_info_)); + SetOnDeviceExpectations(dev_info_); + tm_.OnDeviceListUpdated(mock_adapter_); + + const std::string mac_address("NE:WA:DR:ES:SS"); + const std::string connection_type("TCP"); + const std::string device_name("TestName"); + const transport_manager::DeviceHandle device_handle( + tm_.get_converter().UidToHandle(mac_address, connection_type)); + + DeviceInfo second_device( + device_handle, mac_address, device_name, connection_type); + DeviceList device_list_2; + device_list_2.push_back(second_device.mac_address()); + SetDeviceExpectations(second_mock_adapter, device_list_2, second_device); + + EXPECT_CALL(*tm_listener_, OnDeviceFound(second_device)); + SetOnDeviceExpectations(second_device); + tm_.OnDeviceListUpdated(second_mock_adapter); + + device_list_.pop_back(); + device_list_2.pop_back(); + + EXPECT_CALL(*second_mock_adapter, GetDeviceList()) + .WillRepeatedly(Return(device_list_2)); + EXPECT_CALL(*tm_listener_, OnDeviceRemoved(second_device)); + EXPECT_CALL(*tm_listener_, OnDeviceListUpdated(_)); + tm_.OnDeviceListUpdated(second_mock_adapter); + + EXPECT_CALL(*mock_adapter_, GetDeviceList()) + .WillRepeatedly(Return(device_list_)); + EXPECT_CALL(*tm_listener_, OnDeviceRemoved(dev_info_)); + EXPECT_CALL(*tm_listener_, OnDeviceListUpdated(_)); + tm_.OnDeviceListUpdated(mock_adapter_); +} + } // namespace transport_manager_test } // namespace components } // namespace test |