diff options
Diffstat (limited to 'src/components/transport_manager/src/transport_adapter/transport_adapter_impl.cc')
-rw-r--r-- | src/components/transport_manager/src/transport_adapter/transport_adapter_impl.cc | 220 |
1 files changed, 181 insertions, 39 deletions
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 346139cbd2..fc43cfc63e 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 @@ -31,14 +31,15 @@ */ #include "config_profile/profile.h" -#include "utils/logger.h" #include "utils/helpers.h" +#include "utils/logger.h" +#include "utils/timer_task_impl.h" -#include "transport_manager/transport_adapter/transport_adapter_impl.h" -#include "transport_manager/transport_adapter/transport_adapter_listener.h" +#include "transport_manager/transport_adapter/client_connection_listener.h" #include "transport_manager/transport_adapter/device_scanner.h" #include "transport_manager/transport_adapter/server_connection_factory.h" -#include "transport_manager/transport_adapter/client_connection_listener.h" +#include "transport_manager/transport_adapter/transport_adapter_impl.h" +#include "transport_manager/transport_adapter/transport_adapter_listener.h" namespace transport_manager { namespace transport_adapter { @@ -60,7 +61,9 @@ DeviceTypes devicesType = { std::make_pair(DeviceType::IOS_USB_DEVICE_MODE, std::string("USB_IOS_DEVICE_MODE")), std::make_pair(DeviceType::IOS_CARPLAY_WIRELESS, - std::string("CARPLAY_WIRELESS_IOS"))}; + std::string("CARPLAY_WIRELESS_IOS")), + std::make_pair(DeviceType::CLOUD_WEBSOCKET, + std::string("CLOUD_WEBSOCKET"))}; } TransportAdapterImpl::TransportAdapterImpl( @@ -97,16 +100,16 @@ TransportAdapterImpl::~TransportAdapterImpl() { LOG4CXX_DEBUG(logger_, "device_scanner_ deleted."); } if (server_connection_factory_) { - LOG4CXX_DEBUG(logger_, - "Deleting server_connection_factory " - << server_connection_factory_); + LOG4CXX_DEBUG( + logger_, + "Deleting server_connection_factory " << server_connection_factory_); delete server_connection_factory_; LOG4CXX_DEBUG(logger_, "server_connection_factory deleted."); } if (client_connection_listener_) { - LOG4CXX_DEBUG(logger_, - "Deleting client_connection_listener_ " - << client_connection_listener_); + LOG4CXX_DEBUG( + logger_, + "Deleting client_connection_listener_ " << client_connection_listener_); delete client_connection_listener_; LOG4CXX_DEBUG(logger_, "client_connection_listener_ deleted."); } @@ -190,9 +193,9 @@ TransportAdapter::Error TransportAdapterImpl::SearchDevices() { TransportAdapter::Error TransportAdapterImpl::Connect( const DeviceUID& device_id, const ApplicationHandle& app_handle) { - LOG4CXX_TRACE(logger_, - "enter. DeviceUID " << device_id << " ApplicationHandle " - << app_handle); + LOG4CXX_TRACE( + logger_, + "enter. DeviceUID " << device_id << " ApplicationHandle " << app_handle); if (server_connection_factory_ == 0) { LOG4CXX_TRACE(logger_, "exit with NOT_SUPPORTED"); return NOT_SUPPORTED; @@ -207,17 +210,21 @@ TransportAdapter::Error TransportAdapterImpl::Connect( } connections_lock_.AcquireForWriting(); + + std::pair<DeviceUID, ApplicationHandle> connection_key = + std::make_pair(device_id, app_handle); const bool already_exists = - connections_.end() != - connections_.find(std::make_pair(device_id, app_handle)); + connections_.end() != connections_.find(connection_key); + ConnectionInfo& info = connections_[connection_key]; if (!already_exists) { - ConnectionInfo& info = connections_[std::make_pair(device_id, app_handle)]; info.app_handle = app_handle; info.device_id = device_id; info.state = ConnectionInfo::NEW; } + const bool pending_app = ConnectionInfo::PENDING == info.state; connections_lock_.Release(); - if (already_exists) { + + if (already_exists && !pending_app) { LOG4CXX_TRACE(logger_, "exit with ALREADY_EXISTS"); return ALREADY_EXISTS; } @@ -226,7 +233,9 @@ TransportAdapter::Error TransportAdapterImpl::Connect( server_connection_factory_->CreateConnection(device_id, app_handle); if (TransportAdapter::OK != err) { connections_lock_.AcquireForWriting(); - connections_.erase(std::make_pair(device_id, app_handle)); + if (!pending_app) { + connections_.erase(std::make_pair(device_id, app_handle)); + } connections_lock_.Release(); } LOG4CXX_TRACE(logger_, "exit with error: " << err); @@ -239,6 +248,33 @@ TransportAdapter::Error TransportAdapterImpl::ConnectDevice( DeviceSptr device = FindDevice(device_handle); if (device) { TransportAdapter::Error err = ConnectDevice(device); + if (FAIL == err && GetDeviceType() == DeviceType::CLOUD_WEBSOCKET) { + LOG4CXX_TRACE(logger_, + "Error occurred while connecting cloud app: " << err); + // Update retry count + if (device->retry_count() >= + get_settings().cloud_app_max_retry_attempts()) { + device->reset_retry_count(); + ConnectionStatusUpdated(device, ConnectionStatus::PENDING); + return err; + } else if (device->connection_status() == ConnectionStatus::PENDING) { + ConnectionStatusUpdated(device, ConnectionStatus::RETRY); + } + + device->next_retry(); + + // Start timer for next retry + TimerSPtr retry_timer(std::make_shared<timer::Timer>( + "RetryConnectionTimer", + new timer::TimerTaskImpl<TransportAdapterImpl>( + this, &TransportAdapterImpl::RetryConnection))); + sync_primitives::AutoLock locker(retry_timer_pool_lock_); + retry_timer_pool_.push(std::make_pair(retry_timer, device_handle)); + retry_timer->Start(get_settings().cloud_app_retry_timeout(), + timer::kSingleShot); + } else if (OK == err) { + ConnectionStatusUpdated(device, ConnectionStatus::CONNECTED); + } LOG4CXX_TRACE(logger_, "exit with error: " << err); return err; } else { @@ -247,11 +283,65 @@ TransportAdapter::Error TransportAdapterImpl::ConnectDevice( } } +void TransportAdapterImpl::RetryConnection() { + ClearCompletedTimers(); + const DeviceUID device_id = GetNextRetryDevice(); + if (device_id.empty()) { + LOG4CXX_ERROR(logger_, + "Unable to find timer, ignoring RetryConnection request"); + return; + } + ConnectDevice(device_id); +} + +void TransportAdapterImpl::ClearCompletedTimers() { + // Cleanup any retry timers which have completed execution + sync_primitives::AutoLock locker(completed_timer_pool_lock_); + while (!completed_timer_pool_.empty()) { + auto timer_entry = completed_timer_pool_.front(); + if (timer_entry.first->is_completed()) { + completed_timer_pool_.pop(); + } + } +} + +DeviceUID TransportAdapterImpl::GetNextRetryDevice() { + sync_primitives::AutoLock retry_locker(retry_timer_pool_lock_); + if (retry_timer_pool_.empty()) { + return std::string(); + } + auto timer_entry = retry_timer_pool_.front(); + retry_timer_pool_.pop(); + + // Store reference for cleanup later + sync_primitives::AutoLock completed_locker(completed_timer_pool_lock_); + completed_timer_pool_.push(timer_entry); + + return timer_entry.second; +} + +ConnectionStatus TransportAdapterImpl::GetConnectionStatus( + const DeviceUID& device_handle) const { + DeviceSptr device = FindDevice(device_handle); + return device.use_count() == 0 ? ConnectionStatus::INVALID + : device->connection_status(); +} + +void TransportAdapterImpl::ConnectionStatusUpdated(DeviceSptr device, + ConnectionStatus status) { + device->set_connection_status(status); + for (TransportAdapterListenerList::iterator it = listeners_.begin(); + it != listeners_.end(); + ++it) { + (*it)->OnConnectionStatusUpdated(this); + } +} + TransportAdapter::Error TransportAdapterImpl::Disconnect( const DeviceUID& device_id, const ApplicationHandle& app_handle) { - LOG4CXX_TRACE(logger_, - "enter. device_id: " << &device_id - << ", device_id: " << &device_id); + LOG4CXX_TRACE( + logger_, + "enter. device_id: " << &device_id << ", device_id: " << &device_id); if (!initialised_) { LOG4CXX_TRACE(logger_, "exit with BAD_STATE"); return BAD_STATE; @@ -276,6 +366,8 @@ TransportAdapter::Error TransportAdapterImpl::DisconnectDevice( } Error error = OK; + DeviceSptr device = FindDevice(device_id); + ConnectionStatusUpdated(device, ConnectionStatus::CLOSING); std::vector<ConnectionInfo> to_disconnect; connections_lock_.AcquireForReading(); @@ -395,6 +487,7 @@ DeviceSptr TransportAdapterImpl::AddDevice(DeviceSptr device) { LOG4CXX_TRACE(logger_, "exit with TRUE. Condition: same_device_found"); return existing_device; } else { + device->set_connection_status(ConnectionStatus::PENDING); for (TransportAdapterListenerList::iterator it = listeners_.begin(); it != listeners_.end(); ++it) { @@ -545,9 +638,9 @@ void TransportAdapterImpl::ConnectionCreated( void TransportAdapterImpl::DeviceDisconnected( const DeviceUID& device_handle, const DisconnectDeviceError& error) { const DeviceUID device_uid = device_handle; - LOG4CXX_TRACE(logger_, - "enter. device_handle: " << &device_uid - << ", error: " << &error); + LOG4CXX_TRACE( + logger_, + "enter. device_handle: " << &device_uid << ", error: " << &error); ApplicationList app_list = GetApplicationList(device_uid); for (ApplicationList::const_iterator i = app_list.begin(); i != app_list.end(); @@ -605,9 +698,9 @@ void TransportAdapterImpl::DisconnectDone(const DeviceUID& device_handle, const ApplicationHandle& app_handle) { const DeviceUID device_uid = device_handle; const ApplicationHandle app_uid = app_handle; - LOG4CXX_TRACE(logger_, - "enter. device_id: " << &device_uid - << ", app_handle: " << &app_uid); + LOG4CXX_TRACE( + logger_, + "enter. device_id: " << &device_uid << ", app_handle: " << &app_uid); DeviceSptr device = FindDevice(device_handle); if (!device) { LOG4CXX_WARN(logger_, "Device: uid " << &device_uid << " not found"); @@ -728,6 +821,26 @@ void TransportAdapterImpl::DeviceSwitched(const DeviceUID& device_handle) { UNUSED(device_handle); } +ConnectionSPtr TransportAdapterImpl::FindPendingConnection( + const DeviceUID& device_id, const ApplicationHandle& app_handle) const { + LOG4CXX_TRACE( + logger_, + "enter. device_id: " << &device_id << ", app_handle: " << &app_handle); + ConnectionSPtr connection; + connections_lock_.AcquireForReading(); + ConnectionMap::const_iterator it = + connections_.find(std::make_pair(device_id, app_handle)); + if (it != connections_.end()) { + const ConnectionInfo& info = it->second; + if (info.state == ConnectionInfo::PENDING) { + connection = info.connection; + } + } + connections_lock_.Release(); + LOG4CXX_TRACE(logger_, "exit with Connection: " << connection); + return connection; +} + DeviceSptr TransportAdapterImpl::FindDevice(const DeviceUID& device_id) const { LOG4CXX_TRACE(logger_, "enter. device_id: " << &device_id); DeviceSptr ret; @@ -743,11 +856,39 @@ DeviceSptr TransportAdapterImpl::FindDevice(const DeviceUID& device_id) const { return ret; } +void TransportAdapterImpl::ConnectPending(const DeviceUID& device_id, + const ApplicationHandle& app_handle) { + LOG4CXX_AUTO_TRACE(logger_); + connections_lock_.AcquireForWriting(); + ConnectionMap::iterator it_conn = + connections_.find(std::make_pair(device_id, app_handle)); + if (it_conn != connections_.end()) { + ConnectionInfo& info = it_conn->second; + info.state = ConnectionInfo::PENDING; + } + connections_lock_.Release(); + + DeviceSptr device = FindDevice(device_id); + if (device.use_count() == 0) { + LOG4CXX_ERROR( + logger_, "Unable to find device, cannot set connection pending status"); + return; + } else { + device->set_connection_status(ConnectionStatus::PENDING); + } + + for (TransportAdapterListenerList::iterator it = listeners_.begin(); + it != listeners_.end(); + ++it) { + (*it)->OnConnectPending(this, device_id, app_handle); + } +} + void TransportAdapterImpl::ConnectDone(const DeviceUID& device_id, const ApplicationHandle& app_handle) { - LOG4CXX_TRACE(logger_, - "enter. device_id: " << &device_id - << ", app_handle: " << &app_handle); + LOG4CXX_TRACE( + logger_, + "enter. device_id: " << &device_id << ", app_handle: " << &app_handle); connections_lock_.AcquireForReading(); ConnectionMap::iterator it_conn = connections_.find(std::make_pair(device_id, app_handle)); @@ -834,9 +975,9 @@ ApplicationList TransportAdapterImpl::GetApplicationList( void TransportAdapterImpl::ConnectionFinished( const DeviceUID& device_id, const ApplicationHandle& app_handle) { - LOG4CXX_TRACE(logger_, - "enter. device_id: " << &device_id - << ", app_handle: " << &app_handle); + LOG4CXX_TRACE( + logger_, + "enter. device_id: " << &device_id << ", app_handle: " << &app_handle); connections_lock_.AcquireForReading(); ConnectionMap::iterator it = connections_.find(std::make_pair(device_id, app_handle)); @@ -960,9 +1101,9 @@ bool TransportAdapterImpl::ToBeAutoDisconnected(DeviceSptr device) const { ConnectionSPtr TransportAdapterImpl::FindEstablishedConnection( const DeviceUID& device_id, const ApplicationHandle& app_handle) const { - LOG4CXX_TRACE(logger_, - "enter. device_id: " << &device_id - << ", app_handle: " << &app_handle); + LOG4CXX_TRACE( + logger_, + "enter. device_id: " << &device_id << ", app_handle: " << &app_handle); ConnectionSPtr connection; connections_lock_.AcquireForReading(); ConnectionMap::const_iterator it = @@ -1036,12 +1177,13 @@ void TransportAdapterImpl::RunAppOnDevice(const DeviceUID& device_uid, void TransportAdapterImpl::RemoveDevice(const DeviceUID& device_handle) { LOG4CXX_AUTO_TRACE(logger_); - LOG4CXX_DEBUG(logger_, "Device_handle: " << &device_handle); + LOG4CXX_DEBUG(logger_, "Remove Device_handle: " << &device_handle); sync_primitives::AutoLock locker(devices_mutex_); DeviceMap::iterator i = devices_.find(device_handle); if (i != devices_.end()) { DeviceSptr device = i->second; - if (!device->keep_on_disconnect()) { + bool is_cloud_device = (GetDeviceType() == DeviceType::CLOUD_WEBSOCKET); + if (!device->keep_on_disconnect() || is_cloud_device) { devices_.erase(i); for (TransportAdapterListenerList::iterator it = listeners_.begin(); it != listeners_.end(); |