summaryrefslogtreecommitdiff
path: root/src/components/transport_manager/src/transport_adapter/transport_adapter_impl.cc
diff options
context:
space:
mode:
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.cc220
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();