summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJackLivio <jack@livio.io>2019-01-23 16:34:29 -0500
committerGitHub <noreply@github.com>2019-01-23 16:34:29 -0500
commit709a6584202d23fae54037902df51e132c4e8acb (patch)
tree24bec23ca3fd01c4e8a37ac567d2c3f63d327697
parent9d16c63644d88380aaee1791b5141579ea50c826 (diff)
parent5676f89293d1e5a1a95c06a714072564138a47c4 (diff)
downloadsdl_core-709a6584202d23fae54037902df51e132c4e8acb.tar.gz
Merge pull request #2782 from smartdevicelink/feature/cloud_app_connection_status_disconnect
Cloud App Handle Disconnect
-rw-r--r--src/components/application_manager/include/application_manager/application_manager_impl.h4
-rw-r--r--src/components/application_manager/src/application_manager_impl.cc35
-rw-r--r--src/components/connection_handler/src/connection_handler_impl.cc3
-rw-r--r--src/components/include/connection_handler/connection_handler_observer.h4
-rw-r--r--src/components/include/test/connection_handler/mock_connection_handler_observer.h3
-rw-r--r--src/components/transport_manager/include/transport_manager/cloud/websocket_client_connection.h3
-rw-r--r--src/components/transport_manager/include/transport_manager/transport_adapter/transport_adapter_controller.h4
-rw-r--r--src/components/transport_manager/include/transport_manager/transport_adapter/transport_adapter_impl.h4
-rw-r--r--src/components/transport_manager/src/cloud/cloud_websocket_connection_factory.cc14
-rw-r--r--src/components/transport_manager/src/cloud/cloud_websocket_transport_adapter.cc6
-rw-r--r--src/components/transport_manager/src/cloud/websocket_client_connection.cc24
-rw-r--r--src/components/transport_manager/src/transport_adapter/transport_adapter_impl.cc35
-rw-r--r--src/components/transport_manager/src/transport_manager_impl.cc37
-rw-r--r--src/components/transport_manager/test/include/transport_manager/transport_adapter/mock_transport_adapter_controller.h3
-rw-r--r--src/components/transport_manager/test/tcp_client_listener_test.cc3
15 files changed, 149 insertions, 33 deletions
diff --git a/src/components/application_manager/include/application_manager/application_manager_impl.h b/src/components/application_manager/include/application_manager/application_manager_impl.h
index 8c062f9016..5989605281 100644
--- a/src/components/application_manager/include/application_manager/application_manager_impl.h
+++ b/src/components/application_manager/include/application_manager/application_manager_impl.h
@@ -367,6 +367,10 @@ class ApplicationManagerImpl
const transport_manager::DeviceInfo& device_info,
connection_handler::DeviceHandle device_id);
+ void SetPendingApplicationState(
+ const transport_manager::ConnectionUID connection_id,
+ const transport_manager::DeviceInfo& device_info);
+
/**
* @brief Notifies the applicaiton manager that a cloud connection status has
* updated and should trigger an UpdateAppList RPC to the HMI
diff --git a/src/components/application_manager/src/application_manager_impl.cc b/src/components/application_manager/src/application_manager_impl.cc
index 621d404669..7b2475a4e0 100644
--- a/src/components/application_manager/src/application_manager_impl.cc
+++ b/src/components/application_manager/src/application_manager_impl.cc
@@ -842,9 +842,9 @@ void ApplicationManagerImpl::RefreshCloudAppInformation() {
auto old_device_it = old_device_map.find(endpoint);
if (old_device_it != old_device_map.end()) {
old_device_map.erase(old_device_it);
- continue;
}
+ // If the device was disconnected, this will reinitialize the device
connection_handler().AddCloudAppDevice(endpoint, cloud_transport_type);
}
pending_device_map_lock_ptr_->Release();
@@ -911,6 +911,7 @@ void ApplicationManagerImpl::CreatePendingApplication(
pending_device_map_lock_ptr_->Acquire();
auto it = pending_device_map_.find(name);
if (it == pending_device_map_.end()) {
+ pending_device_map_lock_ptr_->Release();
return;
}
pending_device_map_lock_ptr_->Release();
@@ -988,6 +989,36 @@ void ApplicationManagerImpl::CreatePendingApplication(
SendUpdateAppList();
}
+void ApplicationManagerImpl::SetPendingApplicationState(
+ const transport_manager::ConnectionUID connection_id,
+ const transport_manager::DeviceInfo& device_info) {
+ std::string name = device_info.name();
+ pending_device_map_lock_ptr_->Acquire();
+ auto it = pending_device_map_.find(name);
+ if (it == pending_device_map_.end()) {
+ pending_device_map_lock_ptr_->Release();
+ return;
+ }
+ pending_device_map_lock_ptr_->Release();
+
+ const std::string policy_app_id = it->second;
+ auto app = application_by_policy_id(policy_app_id);
+
+ if (!app) {
+ return;
+ }
+ LOG4CXX_DEBUG(logger_,
+ "Unregister application and move into apps_to_register");
+ {
+ sync_primitives::AutoLock lock(apps_to_register_list_lock_ptr_);
+ apps_to_register_.insert(app);
+ }
+
+ UnregisterApplication(
+ app->app_id(), mobile_apis::Result::INVALID_ENUM, true, true);
+ app->MarkUnregistered();
+}
+
void ApplicationManagerImpl::OnConnectionStatusUpdated() {
SendUpdateAppList();
}
@@ -1232,6 +1263,7 @@ void ApplicationManagerImpl::OnDeviceListUpdated(
so_to_send[jhs::S_PARAMS][jhs::S_CORRELATION_ID] = GetNextHMICorrelationID();
so_to_send[jhs::S_MSG_PARAMS] = *msg_params;
rpc_service_->ManageHMICommand(update_list);
+ RefreshCloudAppInformation();
}
void ApplicationManagerImpl::OnFindNewApplicationsRequest() {
@@ -2708,6 +2740,7 @@ void ApplicationManagerImpl::UnregisterApplication(
logger_, "There is no more SDL4 apps with device handle: " << handle);
RemoveAppsWaitingForRegistration(handle);
+ RefreshCloudAppInformation();
SendUpdateAppList();
}
}
diff --git a/src/components/connection_handler/src/connection_handler_impl.cc b/src/components/connection_handler/src/connection_handler_impl.cc
index 16dbab4117..b58700834f 100644
--- a/src/components/connection_handler/src/connection_handler_impl.cc
+++ b/src/components/connection_handler/src/connection_handler_impl.cc
@@ -286,6 +286,9 @@ void ConnectionHandlerImpl::OnConnectionPending(
connection_handler_observer_->CreatePendingApplication(
connection_id, device_info, device_id);
+ } else {
+ connection_handler_observer_->SetPendingApplicationState(connection_id,
+ device_info);
}
}
diff --git a/src/components/include/connection_handler/connection_handler_observer.h b/src/components/include/connection_handler/connection_handler_observer.h
index f683318ada..b9d6a18926 100644
--- a/src/components/include/connection_handler/connection_handler_observer.h
+++ b/src/components/include/connection_handler/connection_handler_observer.h
@@ -168,6 +168,10 @@ class ConnectionHandlerObserver {
const transport_manager::DeviceInfo& device_info,
connection_handler::DeviceHandle device_id) = 0;
+ virtual void SetPendingApplicationState(
+ const transport_manager::ConnectionUID connection_id,
+ const transport_manager::DeviceInfo& device_info) = 0;
+
protected:
/**
* \brief Destructor
diff --git a/src/components/include/test/connection_handler/mock_connection_handler_observer.h b/src/components/include/test/connection_handler/mock_connection_handler_observer.h
index 0a8e71c085..552be4bee0 100644
--- a/src/components/include/test/connection_handler/mock_connection_handler_observer.h
+++ b/src/components/include/test/connection_handler/mock_connection_handler_observer.h
@@ -79,6 +79,9 @@ class MockConnectionHandlerObserver
void(const transport_manager::ConnectionUID connection_id,
const transport_manager::DeviceInfo& device_info,
connection_handler::DeviceHandle device_id));
+ MOCK_METHOD2(SetPendingApplicationState,
+ void(const transport_manager::ConnectionUID connection_id,
+ const transport_manager::DeviceInfo& device_info));
};
} // namespace connection_handler_test
diff --git a/src/components/transport_manager/include/transport_manager/cloud/websocket_client_connection.h b/src/components/transport_manager/include/transport_manager/cloud/websocket_client_connection.h
index da3a80e1b2..d4319dfe0f 100644
--- a/src/components/transport_manager/include/transport_manager/cloud/websocket_client_connection.h
+++ b/src/components/transport_manager/include/transport_manager/cloud/websocket_client_connection.h
@@ -42,6 +42,7 @@
#include <boost/asio/connect.hpp>
#include <boost/asio/ip/tcp.hpp>
#include <boost/asio/ssl/stream.hpp>
+#include <boost/asio/thread_pool.hpp>
#include <cstdlib>
#include <functional>
#include <iostream>
@@ -170,6 +171,8 @@ class WebsocketClientConnection
const DeviceUID device_uid_;
const ApplicationHandle app_handle_;
+
+ boost::asio::thread_pool io_pool_;
};
} // namespace transport_adapter
diff --git a/src/components/transport_manager/include/transport_manager/transport_adapter/transport_adapter_controller.h b/src/components/transport_manager/include/transport_manager/transport_adapter/transport_adapter_controller.h
index 6d97a55a70..7a0a37758c 100644
--- a/src/components/transport_manager/include/transport_manager/transport_adapter/transport_adapter_controller.h
+++ b/src/components/transport_manager/include/transport_manager/transport_adapter/transport_adapter_controller.h
@@ -88,6 +88,10 @@ class TransportAdapterController {
*/
virtual DeviceSptr FindDevice(const DeviceUID& device_handle) const = 0;
+ virtual ConnectionSPtr FindPendingConnection(
+ const DeviceUID& device_handle,
+ const ApplicationHandle& app_handle) const = 0;
+
/**
* @brief Create connection and fill its parameters.
*
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 68d5ba3067..b30f1e35b2 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
@@ -264,6 +264,10 @@ class TransportAdapterImpl : public TransportAdapter,
*/
DeviceSptr FindDevice(const DeviceUID& device_handle) const OVERRIDE;
+ ConnectionSPtr FindPendingConnection(
+ const DeviceUID& device_handle,
+ const ApplicationHandle& app_handle) const OVERRIDE;
+
/**
* @brief Search for device in container of devices, if it is not there - adds
*it.
diff --git a/src/components/transport_manager/src/cloud/cloud_websocket_connection_factory.cc b/src/components/transport_manager/src/cloud/cloud_websocket_connection_factory.cc
index cdc27ed8ef..0d9fda6fe5 100644
--- a/src/components/transport_manager/src/cloud/cloud_websocket_connection_factory.cc
+++ b/src/components/transport_manager/src/cloud/cloud_websocket_connection_factory.cc
@@ -56,11 +56,15 @@ TransportAdapter::Error CloudWebsocketConnectionFactory::Init() {
TransportAdapter::Error CloudWebsocketConnectionFactory::CreateConnection(
const DeviceUID& device_uid, const ApplicationHandle& app_handle) {
LOG4CXX_AUTO_TRACE(logger_);
- std::shared_ptr<WebsocketClientConnection> connection =
- std::make_shared<WebsocketClientConnection>(
- device_uid, app_handle, controller_);
- controller_->ConnectionCreated(connection, device_uid, app_handle);
- TransportAdapter::Error error = connection->Start();
+ auto connection = controller_->FindPendingConnection(device_uid, app_handle);
+
+ std::shared_ptr<WebsocketClientConnection> ws_connection =
+ std::dynamic_pointer_cast<WebsocketClientConnection>(connection);
+ if (ws_connection.use_count() == 0) {
+ return TransportAdapter::Error::BAD_PARAM;
+ }
+
+ TransportAdapter::Error error = ws_connection->Start();
if (TransportAdapter::OK != error) {
LOG4CXX_ERROR(
logger_,
diff --git a/src/components/transport_manager/src/cloud/cloud_websocket_transport_adapter.cc b/src/components/transport_manager/src/cloud/cloud_websocket_transport_adapter.cc
index 5093e6c2af..9f2b8e6ade 100644
--- a/src/components/transport_manager/src/cloud/cloud_websocket_transport_adapter.cc
+++ b/src/components/transport_manager/src/cloud/cloud_websocket_transport_adapter.cc
@@ -64,6 +64,12 @@ bool CloudWebsocketTransportAdapter::Restore() {
}
void CloudWebsocketTransportAdapter::CreateDevice(const std::string& uid) {
+ // If the device has already been created, just ignore the request
+ DeviceSptr device = FindDevice(uid);
+ if (device.use_count() != 0) {
+ return;
+ }
+
boost::regex pattern(
"(wss?):\\/\\/([A-Z\\d\\.-]{2,})\\.?([A-Z]{2,})?(:\\d{2,4})\\/",
boost::regex::icase);
diff --git a/src/components/transport_manager/src/cloud/websocket_client_connection.cc b/src/components/transport_manager/src/cloud/websocket_client_connection.cc
index e001e8877d..2947c510ff 100644
--- a/src/components/transport_manager/src/cloud/websocket_client_connection.cc
+++ b/src/components/transport_manager/src/cloud/websocket_client_connection.cc
@@ -53,13 +53,12 @@ WebsocketClientConnection::WebsocketClientConnection(
, thread_delegate_(new LoopThreadDelegate(&message_queue_, this))
, write_thread_(threads::CreateThread("WS Async Send", thread_delegate_))
, device_uid_(device_uid)
- , app_handle_(app_handle) {}
+ , app_handle_(app_handle)
+ , io_pool_(1) {}
WebsocketClientConnection::~WebsocketClientConnection() {
ioc_.stop();
- if (io_service_thread_.joinable()) {
- io_service_thread_.join();
- }
+ io_pool_.join();
}
TransportAdapter::Error WebsocketClientConnection::Start() {
@@ -73,7 +72,6 @@ TransportAdapter::Error WebsocketClientConnection::Start() {
if (ec) {
std::string str_err = "ErrorMessage: " + ec.message();
LOG4CXX_ERROR(logger_, "Could not resolve host/port: " << str_err);
- Shutdown();
return TransportAdapter::FAIL;
}
boost::asio::connect(ws_.next_layer(), results.begin(), results.end(), ec);
@@ -82,7 +80,6 @@ TransportAdapter::Error WebsocketClientConnection::Start() {
LOG4CXX_ERROR(logger_,
"Could not connect to websocket: " << host << ":" << port);
LOG4CXX_ERROR(logger_, str_err);
- Shutdown();
return TransportAdapter::FAIL;
}
ws_.handshake(host, "/", ec);
@@ -92,7 +89,6 @@ TransportAdapter::Error WebsocketClientConnection::Start() {
"Could not complete handshake with host/port: " << host << ":"
<< port);
LOG4CXX_ERROR(logger_, str_err);
- Shutdown();
return TransportAdapter::FAIL;
}
ws_.binary(true);
@@ -106,16 +102,11 @@ TransportAdapter::Error WebsocketClientConnection::Start() {
std::placeholders::_1,
std::placeholders::_2));
- // Start IO Service thread. Allows for async reads without blocking.
- io_service_thread_ = std::thread([&]() {
- ioc_.run();
- LOG4CXX_DEBUG(logger_, "Ending Boost IO Thread");
- });
+ boost::asio::post(io_pool_, [&]() { ioc_.run(); });
LOG4CXX_DEBUG(logger_,
"Successfully started websocket connection @: " << host << ":"
<< port);
-
return TransportAdapter::OK;
}
@@ -144,14 +135,12 @@ void WebsocketClientConnection::OnRead(boost::system::error_code ec,
if (ec) {
std::string str_err = "ErrorMessage: " + ec.message();
LOG4CXX_ERROR(logger_, str_err);
+ ws_.lowest_layer().close();
+ ioc_.stop();
Shutdown();
- controller_->ConnectionAborted(
- device_uid_, app_handle_, CommunicationError());
return;
}
-
std::string data_str = boost::beast::buffers_to_string(buffer_.data());
- LOG4CXX_DEBUG(logger_, "Cloud Transport Received: " << data_str);
ssize_t size = (ssize_t)buffer_.size();
const uint8_t* data = boost::asio::buffer_cast<const uint8_t*>(
@@ -224,7 +213,6 @@ void WebsocketClientConnection::LoopThreadDelegate::DrainQueue() {
boost::asio::buffer(message_ptr->data(), message_ptr->data_size()));
if (ec) {
LOG4CXX_ERROR(logger_, "Error writing to websocket");
- handler_.Shutdown();
handler_.controller_->DataSendFailed(handler_.device_uid_,
handler_.app_handle_,
message_ptr,
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 34d5a29abd..335770bea7 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
@@ -233,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);
@@ -819,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;
@@ -836,7 +858,8 @@ DeviceSptr TransportAdapterImpl::FindDevice(const DeviceUID& device_id) const {
void TransportAdapterImpl::ConnectPending(const DeviceUID& device_id,
const ApplicationHandle& app_handle) {
- connections_lock_.AcquireForReading();
+ 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()) {
@@ -845,6 +868,14 @@ void TransportAdapterImpl::ConnectPending(const DeviceUID& device_id,
}
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");
+ } else {
+ device->set_connection_status(ConnectionStatus::PENDING);
+ }
+
for (TransportAdapterListenerList::iterator it = listeners_.begin();
it != listeners_.end();
++it) {
diff --git a/src/components/transport_manager/src/transport_manager_impl.cc b/src/components/transport_manager/src/transport_manager_impl.cc
index 301132d26f..0b8724ff85 100644
--- a/src/components/transport_manager/src/transport_manager_impl.cc
+++ b/src/components/transport_manager/src/transport_manager_impl.cc
@@ -1002,19 +1002,42 @@ void TransportManagerImpl::Handle(TransportAdapterEvent event) {
case EventTypeEnum::ON_CONNECT_PENDING: {
const DeviceHandle device_handle = converter_.UidToHandle(
event.device_uid, event.transport_adapter->GetConnectionType());
- AddConnection(ConnectionInternal(this,
- event.transport_adapter,
- ++connection_id_counter_,
- event.device_uid,
- event.application_id,
- device_handle));
+ int connection_id = 0;
+ std::vector<ConnectionInternal>::iterator it = connections_.begin();
+ std::vector<ConnectionInternal>::iterator end = connections_.end();
+ for (; it != end; ++it) {
+ if (it->transport_adapter != event.transport_adapter) {
+ continue;
+ } else if (it->Connection::device != event.device_uid) {
+ continue;
+ } else if (it->Connection::application != event.application_id) {
+ continue;
+ } else if (it->device_handle_ != device_handle) {
+ continue;
+ } else {
+ LOG4CXX_DEBUG(logger_, "Connection Object Already Exists");
+ connection_id = it->Connection::id;
+ break;
+ }
+ }
+
+ if (it == end) {
+ AddConnection(ConnectionInternal(this,
+ event.transport_adapter,
+ ++connection_id_counter_,
+ event.device_uid,
+ event.application_id,
+ device_handle));
+ connection_id = connection_id_counter_;
+ }
+
RaiseEvent(
&TransportManagerListener::OnConnectionPending,
DeviceInfo(device_handle,
event.device_uid,
event.transport_adapter->DeviceName(event.device_uid),
event.transport_adapter->GetConnectionType()),
- connection_id_counter_);
+ connection_id);
LOG4CXX_DEBUG(logger_, "event_type = ON_CONNECT_PENDING");
break;
}
diff --git a/src/components/transport_manager/test/include/transport_manager/transport_adapter/mock_transport_adapter_controller.h b/src/components/transport_manager/test/include/transport_manager/transport_adapter/mock_transport_adapter_controller.h
index 642c193d63..1de5eac702 100644
--- a/src/components/transport_manager/test/include/transport_manager/transport_adapter/mock_transport_adapter_controller.h
+++ b/src/components/transport_manager/test/include/transport_manager/transport_adapter/mock_transport_adapter_controller.h
@@ -55,6 +55,9 @@ class MockTransportAdapterController : public TransportAdapterController {
void(ConnectionSPtr connection,
const DeviceUID& device_handle,
const ApplicationHandle& app_handle));
+ MOCK_CONST_METHOD2(FindPendingConnection,
+ ConnectionSPtr(const DeviceUID& device_handle,
+ const ApplicationHandle& app_handle));
MOCK_METHOD2(ConnectDone,
void(const DeviceUID& device_handle,
const ApplicationHandle& app_handle));
diff --git a/src/components/transport_manager/test/tcp_client_listener_test.cc b/src/components/transport_manager/test/tcp_client_listener_test.cc
index f44f8785aa..1f4a17cf6c 100644
--- a/src/components/transport_manager/test/tcp_client_listener_test.cc
+++ b/src/components/transport_manager/test/tcp_client_listener_test.cc
@@ -69,6 +69,9 @@ class MockTransportAdapterController : public TransportAdapterController {
MOCK_METHOD1(SearchDeviceDone, void(const DeviceVector& devices));
MOCK_METHOD1(SearchDeviceFailed, void(const SearchDeviceError& error));
MOCK_CONST_METHOD1(FindDevice, DeviceSptr(const DeviceUID& device_handle));
+ MOCK_CONST_METHOD2(FindPendingConnection,
+ ConnectionSPtr(const DeviceUID& device_handle,
+ const ApplicationHandle& app_handle));
MOCK_METHOD3(ConnectionCreated,
void(ConnectionSPtr connection,
const DeviceUID& device_handle,