summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJackLivio <jack@livio.io>2019-01-22 13:27:43 -0500
committerGitHub <noreply@github.com>2019-01-22 13:27:43 -0500
commit8768bf96919413230d23f859b563bd95e6629e35 (patch)
tree924088cc34ba1ecb64a128e325ab0b5eaf41927b
parent8b15b81ea2a8e35d69c6c7cb9841b9b451ab0c11 (diff)
parent9f48c541b2ffefb0c34aacc22075cab849dcaea4 (diff)
downloadsdl_core-8768bf96919413230d23f859b563bd95e6629e35.tar.gz
Merge pull request #2742 from smartdevicelink/feature/cloud_app_connection_flow
Cloud app connection flow
-rw-r--r--CMakeLists.txt6
-rw-r--r--src/3rd_party/CMakeLists.txt6
-rw-r--r--src/appMain/smartDeviceLink.ini6
-rw-r--r--src/components/application_manager/include/application_manager/application.h61
-rw-r--r--src/components/application_manager/include/application_manager/application_impl.h67
-rw-r--r--src/components/application_manager/include/application_manager/application_manager_impl.h9
-rw-r--r--src/components/application_manager/src/application_impl.cc44
-rw-r--r--src/components/application_manager/src/application_manager_impl.cc118
-rw-r--r--src/components/application_manager/test/include/application_manager/mock_application.h14
-rw-r--r--src/components/config_profile/include/config_profile/profile.h12
-rw-r--r--src/components/config_profile/src/profile.cc33
-rw-r--r--src/components/connection_handler/include/connection_handler/connection_handler_impl.h11
-rw-r--r--src/components/connection_handler/src/connection_handler_impl.cc66
-rw-r--r--src/components/include/connection_handler/connection_handler.h3
-rw-r--r--src/components/include/connection_handler/connection_handler_observer.h5
-rw-r--r--src/components/include/test/connection_handler/mock_connection_handler.h3
-rw-r--r--src/components/include/test/connection_handler/mock_connection_handler_observer.h4
-rw-r--r--src/components/include/test/transport_manager/mock_transport_manager.h3
-rw-r--r--src/components/include/test/transport_manager/mock_transport_manager_listener.h3
-rw-r--r--src/components/include/test/transport_manager/mock_transport_manager_settings.h2
-rw-r--r--src/components/include/test/transport_manager/transport_adapter/mock_transport_adapter.h2
-rw-r--r--src/components/include/transport_manager/transport_adapter/transport_adapter.h3
-rw-r--r--src/components/include/transport_manager/transport_adapter/transport_adapter_event.h3
-rw-r--r--src/components/include/transport_manager/transport_manager.h3
-rw-r--r--src/components/include/transport_manager/transport_manager_listener.h8
-rw-r--r--src/components/include/transport_manager/transport_manager_listener_empty.h9
-rw-r--r--src/components/include/transport_manager/transport_manager_settings.h10
-rw-r--r--src/components/interfaces/HMI_API.xml1
-rw-r--r--src/components/protocol_handler/include/protocol_handler/protocol_handler_impl.h4
-rw-r--r--src/components/protocol_handler/src/protocol_handler_impl.cc4
-rw-r--r--src/components/transport_manager/CMakeLists.txt6
-rw-r--r--src/components/transport_manager/include/transport_manager/cloud/cloud_device.h67
-rw-r--r--src/components/transport_manager/include/transport_manager/cloud/cloud_websocket_connection_factory.h98
-rw-r--r--src/components/transport_manager/include/transport_manager/cloud/cloud_websocket_transport_adapter.h89
-rw-r--r--src/components/transport_manager/include/transport_manager/cloud/websocket_client_connection.h178
-rw-r--r--src/components/transport_manager/include/transport_manager/transport_adapter/transport_adapter_controller.h10
-rw-r--r--src/components/transport_manager/include/transport_manager/transport_adapter/transport_adapter_impl.h16
-rw-r--r--src/components/transport_manager/include/transport_manager/transport_adapter/transport_adapter_listener.h13
-rw-r--r--src/components/transport_manager/include/transport_manager/transport_adapter/transport_adapter_listener_impl.h13
-rw-r--r--src/components/transport_manager/include/transport_manager/transport_manager_impl.h3
-rw-r--r--src/components/transport_manager/src/cloud/cloud_device.cc75
-rw-r--r--src/components/transport_manager/src/cloud/cloud_websocket_connection_factory.cc81
-rw-r--r--src/components/transport_manager/src/cloud/cloud_websocket_transport_adapter.cc104
-rw-r--r--src/components/transport_manager/src/cloud/websocket_client_connection.cc244
-rw-r--r--src/components/transport_manager/src/transport_adapter/transport_adapter_impl.cc22
-rw-r--r--src/components/transport_manager/src/transport_adapter/transport_adapter_listener_impl.cc21
-rw-r--r--src/components/transport_manager/src/transport_manager_default.cc18
-rw-r--r--src/components/transport_manager/src/transport_manager_impl.cc67
-rw-r--r--src/components/transport_manager/test/CMakeLists.txt5
-rw-r--r--src/components/transport_manager/test/include/transport_manager/mock_transport_manager_listener.h3
-rw-r--r--src/components/transport_manager/test/include/transport_manager/transport_adapter/mock_transport_adapter_listener.h4
-rw-r--r--src/components/transport_manager/test/tcp_client_listener_test.cc3
52 files changed, 1647 insertions, 16 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1a180b6cf9..f6ee77a143 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -43,6 +43,7 @@ option(EXTENDED_MEDIA_MODE "Turn on and off extended Madia Manager features rela
option(BUILD_SHARED_LIBS "Build all libraries as shared (if ON) or static (if OFF)" OFF)
option(BUILD_BT_SUPPORT "Bluetooth support" ON)
option(BUILD_USB_SUPPORT "libusb support" ON)
+option(BUILD_CLOUD_APP_SUPPORT "Cloud App Transport Support" ON)
option(BUILD_BACKTRACE_SUPPORT "backtrace support" ON)
option(BUILD_TESTS "Possibility to build and run tests" OFF)
option(TELEMETRY_MONITOR "Enable profiling time test util" ON)
@@ -315,6 +316,11 @@ if (BUILD_BT_SUPPORT)
message(STATUS "Bluetooth support enabled")
endif()
+if (BUILD_CLOUD_APP_SUPPORT)
+ add_definitions(-DCLOUD_APP_WEBSOCKET_TRANSPORT_SUPPORT)
+ message(STATUS "Cloud app websocket support enabled")
+endif()
+
if (BUILD_BACKTRACE_SUPPORT)
add_definitions(-DBACKTRACE_SUPPORT)
message(STATUS "Backtrace support enabled")
diff --git a/src/3rd_party/CMakeLists.txt b/src/3rd_party/CMakeLists.txt
index bdb96de417..60d68e9d60 100644
--- a/src/3rd_party/CMakeLists.txt
+++ b/src/3rd_party/CMakeLists.txt
@@ -209,7 +209,7 @@ else()
)
endif()
-find_package(Boost 1.66.0 COMPONENTS system thread date_time filesystem)
+find_package(Boost 1.66.0 COMPONENTS system thread date_time filesystem regex)
set(BOOST_LIB_SOURCE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/boost_src)
set(BOOST_LIBS_DIRECTORY ${3RD_PARTY_INSTALL_PREFIX}/lib)
SET_PROPERTY(GLOBAL PROPERTY GLOBAL_BOOST_LIBS ${BOOST_LIBS_DIRECTORY})
@@ -226,9 +226,9 @@ if (NOT ${Boost_FOUND})
URL https://dl.bintray.com/boostorg/release/1.66.0/source/boost_1_66_0.tar.gz
DOWNLOAD_DIR ${BOOST_LIB_SOURCE_DIRECTORY}
SOURCE_DIR ${BOOST_LIB_SOURCE_DIRECTORY}
- CONFIGURE_COMMAND ./bootstrap.sh --with-libraries=system,thread,date_time,filesystem --prefix=${3RD_PARTY_INSTALL_PREFIX}
+ CONFIGURE_COMMAND ./bootstrap.sh --with-libraries=system,thread,date_time,filesystem,regex --prefix=${3RD_PARTY_INSTALL_PREFIX}
BUILD_COMMAND ./b2
- INSTALL_COMMAND ${BOOST_INSTALL_COMMAND} --with-system --with-thread --with-date_time --with-filesystem --prefix=${3RD_PARTY_INSTALL_PREFIX} > boost_install.log
+ INSTALL_COMMAND ${BOOST_INSTALL_COMMAND} --with-system --with-thread --with-date_time --with-filesystem --with-regex --prefix=${3RD_PARTY_INSTALL_PREFIX} > boost_install.log
INSTALL_DIR ${3RD_PARTY_INSTALL_PREFIX}
BUILD_IN_SOURCE true
)
diff --git a/src/appMain/smartDeviceLink.ini b/src/appMain/smartDeviceLink.ini
index b0513c076f..ccb377d1e6 100644
--- a/src/appMain/smartDeviceLink.ini
+++ b/src/appMain/smartDeviceLink.ini
@@ -202,6 +202,12 @@ TCPAdapterPort = 12345
; If the name is omitted, Core will listen on all network interfaces by binding to INADDR_ANY.
TCPAdapterNetworkInterface =
+[CloudAppConnections]
+; Value in milliseconds for time between retry attempts on a failed websocket connection
+CloudAppRetryTimeout = 1000
+; MaxNn number of retry attempts for a cloud websocket connection
+CloudAppMaxRetryAttempts = 5
+
[ProtocolHandler]
; SDL supported protocol version
MaxSupportedProtocolVersion = 5
diff --git a/src/components/application_manager/include/application_manager/application.h b/src/components/application_manager/include/application_manager/application.h
index ad7570955e..2abd2eaea0 100644
--- a/src/components/application_manager/include/application_manager/application.h
+++ b/src/components/application_manager/include/application_manager/application.h
@@ -946,6 +946,67 @@ class Application : public virtual InitialApplicationData,
*/
virtual const std::list<AppExtensionPtr>& Extensions() const = 0;
+ /**
+ * @brief Get cloud app endpoint for websocket connection
+ * @return cloud app endpoint
+ */
+ virtual const std::string& cloud_app_endpoint() const = 0;
+
+ /**
+ * @brief Get cloud app auth token to be used in connection handshake after
+ * websocket open.
+ * @return cloud app auth token
+ */
+ virtual const std::string& cloud_app_auth_token() const = 0;
+
+ /**
+ * @brief Get cloud app tranpsport type. Defines the type of websocket
+ * connection used.
+ * @return cloud app transport type
+ */
+ virtual const std::string& cloud_app_transport_type() const = 0;
+
+ /**
+ * @brief Get hybrid app preference. Defines behaviour for when a similar
+ * mobile and cloud app are connected simultaneously.
+ * @return hybrid app preference
+ */
+ virtual const mobile_apis::HybridAppPreference::eType& hybrid_app_preference()
+ const = 0;
+
+ /**
+ * @brief Get cloud app certificate. Used for secured websocket connections.
+ * @return cloud app certificate.
+ */
+ virtual const std::string& cloud_app_certificate() const = 0;
+
+ /**
+ * @brief Set cloud app endpoint
+ */
+ virtual void set_cloud_app_endpoint(const std::string& endpoint) = 0;
+
+ /**
+ * @brief Set cloud app auth token
+ */
+ virtual void set_cloud_app_auth_token(const std::string& auth_token) = 0;
+
+ /**
+ * @brief Set cloud app transport type
+ */
+ virtual void set_cloud_app_transport_type(
+ const std::string& transport_type) = 0;
+
+ /**
+ * @brief Set hybrid app preference
+ */
+ virtual void set_hybrid_app_preference(
+ const mobile_apis::HybridAppPreference::eType& hybrid_app_preference) = 0;
+
+ /**
+ * @brief Set cloud app certificate
+ */
+ virtual void set_cloud_app_certificate(const std::string& certificate) = 0;
+
protected:
mutable sync_primitives::Lock hmi_states_lock_;
diff --git a/src/components/application_manager/include/application_manager/application_impl.h b/src/components/application_manager/include/application_manager/application_impl.h
index 8dc3b2da20..0b43b014b6 100644
--- a/src/components/application_manager/include/application_manager/application_impl.h
+++ b/src/components/application_manager/include/application_manager/application_impl.h
@@ -409,6 +409,66 @@ class ApplicationImpl : public virtual Application,
void SwapMobileMessageQueue(MobileMessageQueue& mobile_messages) OVERRIDE;
+ /**
+ * @brief Get cloud app endpoint for websocket connection
+ * @return cloud app endpoint
+ */
+ const std::string& cloud_app_endpoint() const OVERRIDE;
+
+ /**
+ * @brief Get cloud app auth token to be used in connection handshake after
+ * websocket open.
+ * @return cloud app auth token
+ */
+ const std::string& cloud_app_auth_token() const OVERRIDE;
+
+ /**
+ * @brief Get cloud app tranpsport type. Defines the type of websocket
+ * connection used.
+ * @return cloud app transport type
+ */
+ const std::string& cloud_app_transport_type() const OVERRIDE;
+
+ /**
+ * @brief Get hybrid app preference. Defines behaviour for when a similar
+ * mobile and cloud app are connected simultaneously.
+ * @return hybrid app preference
+ */
+ const mobile_apis::HybridAppPreference::eType& hybrid_app_preference()
+ const OVERRIDE;
+
+ /**
+ * @brief Get cloud app certificate. Used for secured websocket connections.
+ * @return cloud app certificate.
+ */
+ const std::string& cloud_app_certificate() const OVERRIDE;
+
+ /**
+ * @brief Set cloud app endpoint
+ */
+ void set_cloud_app_endpoint(const std::string& endpoint) OVERRIDE;
+
+ /**
+ * @brief Set cloud app auth token
+ */
+ void set_cloud_app_auth_token(const std::string& auth_token) OVERRIDE;
+
+ /**
+ * @brief Set cloud app transport type
+ */
+ void set_cloud_app_transport_type(const std::string& transport_type) OVERRIDE;
+
+ /**
+ * @brief Set hybrid app preference
+ */
+ void set_hybrid_app_preference(const mobile_apis::HybridAppPreference::eType&
+ hybrid_app_preference) OVERRIDE;
+
+ /**
+ * @brief Set cloud app certificate
+ */
+ void set_cloud_app_certificate(const std::string& certificate) OVERRIDE;
+
protected:
/**
* @brief Clean up application folder. Persistent files will stay
@@ -513,6 +573,13 @@ class ApplicationImpl : public virtual Application,
std::list<AppExtensionPtr> extensions_;
+ // Cloud app properties
+ std::string endpoint_;
+ std::string auth_token_;
+ std::string cloud_transport_type_;
+ mobile_apis::HybridAppPreference::eType hybrid_app_preference_;
+ std::string certificate_;
+
/**
* @brief Defines number per time in seconds limits
*/
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 6c111dbbb3..20b8c561a3 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
@@ -360,6 +360,13 @@ class ApplicationManagerImpl
void ConnectToDevice(const std::string& device_mac) OVERRIDE;
void OnHMIStartedCooperation() OVERRIDE;
+ void CollectCloudAppInformation();
+
+ void CreatePendingApplication(
+ const transport_manager::ConnectionUID connection_id,
+ const transport_manager::DeviceInfo& device_info,
+ connection_handler::DeviceHandle device_id);
+
/*
* @brief Returns unique correlation ID for HMI request
*
@@ -1449,6 +1456,8 @@ class ApplicationManagerImpl
DeviceMap secondary_transport_devices_cache_;
+ std::map<std::string, std::string> pending_device_map_;
+
#ifdef TELEMETRY_MONITOR
AMTelemetryObserver* metric_observer_;
#endif // TELEMETRY_MONITOR
diff --git a/src/components/application_manager/src/application_impl.cc b/src/components/application_manager/src/application_impl.cc
index 8a611195c7..558a4638c1 100644
--- a/src/components/application_manager/src/application_impl.cc
+++ b/src/components/application_manager/src/application_impl.cc
@@ -1163,6 +1163,50 @@ const std::list<AppExtensionPtr>& ApplicationImpl::Extensions() const {
return extensions_;
}
+const std::string& ApplicationImpl::cloud_app_endpoint() const {
+ return endpoint_;
+}
+
+const std::string& ApplicationImpl::cloud_app_auth_token() const {
+ return auth_token_;
+}
+
+const std::string& ApplicationImpl::cloud_app_transport_type() const {
+ return cloud_transport_type_;
+}
+
+const mobile_apis::HybridAppPreference::eType&
+ApplicationImpl::hybrid_app_preference() const {
+ return hybrid_app_preference_;
+}
+
+const std::string& ApplicationImpl::cloud_app_certificate() const {
+ return certificate_;
+}
+
+void ApplicationImpl::set_cloud_app_endpoint(const std::string& endpoint) {
+ endpoint_ = endpoint;
+}
+
+void ApplicationImpl::set_cloud_app_auth_token(const std::string& auth_token) {
+ auth_token_ = auth_token;
+}
+
+void ApplicationImpl::set_cloud_app_transport_type(
+ const std::string& transport_type) {
+ cloud_transport_type_ = transport_type;
+}
+
+void ApplicationImpl::set_hybrid_app_preference(
+ const mobile_apis::HybridAppPreference::eType& hybrid_app_preference) {
+ hybrid_app_preference_ = hybrid_app_preference;
+}
+
+void ApplicationImpl::set_cloud_app_certificate(
+ const std::string& certificate) {
+ certificate_ = certificate;
+}
+
void ApplicationImpl::PushMobileMessage(
smart_objects::SmartObjectSPtr mobile_message) {
sync_primitives::AutoLock lock(mobile_message_lock_);
diff --git a/src/components/application_manager/src/application_manager_impl.cc b/src/components/application_manager/src/application_manager_impl.cc
index 24f27af2e2..3b5c1b2c7c 100644
--- a/src/components/application_manager/src/application_manager_impl.cc
+++ b/src/components/application_manager/src/application_manager_impl.cc
@@ -98,7 +98,9 @@ DeviceTypes devicesType = {
std::make_pair(std::string("USB_IOS_DEVICE_MODE"),
hmi_apis::Common_TransportType::USB_IOS),
std::make_pair(std::string("CARPLAY_WIRELESS_IOS"),
- hmi_apis::Common_TransportType::WIFI)};
+ hmi_apis::Common_TransportType::WIFI),
+ std::make_pair(std::string("CLOUD_WEBSOCKET"),
+ hmi_apis::Common_TransportType::CLOUD_WEBSOCKET)};
}
/**
@@ -779,6 +781,120 @@ void ApplicationManagerImpl::OnHMIStartedCooperation() {
*this));
rpc_service_->ManageHMICommand(mixing_audio_supported_request);
resume_controller().ResetLaunchTime();
+
+ CollectCloudAppInformation();
+}
+
+void ApplicationManagerImpl::CollectCloudAppInformation() {
+ std::vector<std::string> cloud_app_id_vector;
+ GetPolicyHandler().GetEnabledCloudApps(cloud_app_id_vector);
+ std::vector<std::string>::iterator it = cloud_app_id_vector.begin();
+ std::vector<std::string>::iterator end = cloud_app_id_vector.end();
+ std::string endpoint = "";
+ std::string certificate = "";
+ std::string auth_token = "";
+ std::string cloud_transport_type = "";
+ std::string hybrid_app_preference = "";
+ bool enabled = true;
+ for (; it != end; ++it) {
+ GetPolicyHandler().GetCloudAppParameters(*it,
+ enabled,
+ endpoint,
+ certificate,
+ auth_token,
+ cloud_transport_type,
+ hybrid_app_preference);
+
+ pending_device_map_.insert(
+ std::pair<std::string, std::string>(endpoint, *it));
+
+ connection_handler().AddCloudAppDevice(endpoint, cloud_transport_type);
+ }
+}
+
+void ApplicationManagerImpl::CreatePendingApplication(
+ const transport_manager::ConnectionUID connection_id,
+ const transport_manager::DeviceInfo& device_info,
+ connection_handler::DeviceHandle device_id) {
+ LOG4CXX_AUTO_TRACE(logger_);
+
+ std::string endpoint = "";
+ std::string certificate = "";
+ std::string auth_token = "";
+ std::string cloud_transport_type = "";
+ std::string hybrid_app_preference_str = "";
+ bool enabled = true;
+ std::string name = device_info.name();
+ auto it = pending_device_map_.find(name);
+ if (it == pending_device_map_.end()) {
+ return;
+ }
+
+ const std::string policy_app_id = it->second;
+
+ policy::StringArray nicknames;
+ policy::StringArray app_hmi_types;
+
+ GetPolicyHandler().GetInitialAppData(
+ policy_app_id, &nicknames, &app_hmi_types);
+
+ if (!nicknames.size()) {
+ LOG4CXX_ERROR(logger_, "Cloud App missing nickname");
+ return;
+ }
+
+ const std::string display_name = nicknames[0];
+
+ ApplicationSharedPtr application(
+ new ApplicationImpl(0,
+ policy_app_id,
+ device_info.mac_address(),
+ device_id,
+ custom_str::CustomString(display_name),
+ GetPolicyHandler().GetStatisticManager(),
+ *this));
+
+ if (!application) {
+ LOG4CXX_INFO(logger_, "Could not streate application");
+ return;
+ }
+
+ GetPolicyHandler().GetCloudAppParameters(policy_app_id,
+ enabled,
+ endpoint,
+ certificate,
+ auth_token,
+ cloud_transport_type,
+ hybrid_app_preference_str);
+
+ mobile_apis::HybridAppPreference::eType hybrid_app_preference_enum;
+
+ bool convert_result = smart_objects::EnumConversionHelper<
+ mobile_apis::HybridAppPreference::eType>::
+ StringToEnum(hybrid_app_preference_str, &hybrid_app_preference_enum);
+
+ if (!hybrid_app_preference_str.empty() && !convert_result) {
+ LOG4CXX_ERROR(
+ logger_,
+ "Could not convert string to enum: " << hybrid_app_preference_str);
+ return;
+ }
+
+ application->set_hmi_application_id(GenerateNewHMIAppID());
+ application->set_cloud_app_endpoint(endpoint);
+ application->set_cloud_app_auth_token(auth_token);
+ application->set_cloud_app_transport_type(cloud_transport_type);
+ application->set_hybrid_app_preference(hybrid_app_preference_enum);
+ application->set_cloud_app_certificate(certificate);
+
+ sync_primitives::AutoLock lock(apps_to_register_list_lock_ptr_);
+ LOG4CXX_DEBUG(logger_,
+ "apps_to_register_ size before: " << apps_to_register_.size());
+ apps_to_register_.insert(application);
+ LOG4CXX_DEBUG(logger_,
+ "apps_to_register_ size after: " << apps_to_register_.size());
+
+ SendUpdateAppList();
}
uint32_t ApplicationManagerImpl::GetNextHMICorrelationID() {
diff --git a/src/components/application_manager/test/include/application_manager/mock_application.h b/src/components/application_manager/test/include/application_manager/mock_application.h
index fe16e8ce6e..9c9041284c 100644
--- a/src/components/application_manager/test/include/application_manager/mock_application.h
+++ b/src/components/application_manager/test/include/application_manager/mock_application.h
@@ -342,6 +342,20 @@ class MockApplication : public ::application_manager::Application {
const std::list<application_manager::AppExtensionPtr>&());
MOCK_CONST_METHOD0(is_remote_control_supported, bool());
MOCK_METHOD1(set_remote_control_supported, void(const bool allow));
+ MOCK_CONST_METHOD0(cloud_app_endpoint, const std::string&());
+ MOCK_CONST_METHOD0(cloud_app_auth_token, const std::string&());
+ MOCK_CONST_METHOD0(cloud_app_transport_type, const std::string&());
+ MOCK_CONST_METHOD0(hybrid_app_preference,
+ const mobile_apis::HybridAppPreference::eType&());
+ MOCK_CONST_METHOD0(cloud_app_certificate, const std::string&());
+ MOCK_METHOD1(set_cloud_app_endpoint, void(const std::string& endpoint));
+ MOCK_METHOD1(set_cloud_app_auth_token, void(const std::string& auth_token));
+ MOCK_METHOD1(set_cloud_app_transport_type,
+ void(const std::string& transport_type));
+ MOCK_METHOD1(set_hybrid_app_preference,
+ void(const mobile_apis::HybridAppPreference::eType&
+ hybrid_app_preference));
+ MOCK_METHOD1(set_cloud_app_certificate, void(const std::string& certificate));
};
} // namespace application_manager_test
diff --git a/src/components/config_profile/include/config_profile/profile.h b/src/components/config_profile/include/config_profile/profile.h
index 57e925cd43..4846648b2b 100644
--- a/src/components/config_profile/include/config_profile/profile.h
+++ b/src/components/config_profile/include/config_profile/profile.h
@@ -413,6 +413,16 @@ class Profile : public protocol_handler::ProtocolHandlerSettings,
const std::string& transport_manager_tcp_adapter_network_interface()
const OVERRIDE;
+ /**
+ * @brief Returns retry timeout for cloud app connections
+ */
+ uint32_t cloud_app_retry_timeout() const OVERRIDE;
+
+ /**
+ * @brief Returns maximum retry attempts for cloud app connections
+ */
+ uint16_t cloud_app_max_retry_attempts() const OVERRIDE;
+
// TransportManageMMESettings interface
const std::string& event_mq_name() const OVERRIDE;
@@ -960,6 +970,8 @@ class Profile : public protocol_handler::ProtocolHandlerSettings,
std::string system_files_path_;
uint16_t transport_manager_tcp_adapter_port_;
std::string transport_manager_tcp_adapter_network_interface_;
+ uint32_t cloud_app_retry_timeout_;
+ uint16_t cloud_app_max_retry_attempts_;
std::string tts_delimiter_;
uint32_t audio_data_stopped_timeout_;
uint32_t video_data_stopped_timeout_;
diff --git a/src/components/config_profile/src/profile.cc b/src/components/config_profile/src/profile.cc
index 57984324aa..38afdbf35b 100644
--- a/src/components/config_profile/src/profile.cc
+++ b/src/components/config_profile/src/profile.cc
@@ -81,6 +81,7 @@ const char* kMediaManagerSection = "MEDIA MANAGER";
const char* kGlobalPropertiesSection = "GLOBAL PROPERTIES";
const char* kVrCommandsSection = "VR COMMANDS";
const char* kTransportManagerSection = "TransportManager";
+const char* kCloudAppTransportSection = "CloudAppConnections";
const char* kApplicationManagerSection = "ApplicationManager";
const char* kFilesystemRestrictionsSection = "FILESYSTEM RESTRICTIONS";
const char* kIAPSection = "IAP";
@@ -154,6 +155,8 @@ const char* kMaxSupportedProtocolVersionKey = "MaxSupportedProtocolVersion";
const char* kUseLastStateKey = "UseLastState";
const char* kTCPAdapterPortKey = "TCPAdapterPort";
const char* kTCPAdapterNetworkInterfaceKey = "TCPAdapterNetworkInterface";
+const char* kCloudAppRetryTimeoutKey = "CloudAppRetryTimeout";
+const char* kCloudAppMaxRetryAttemptsKey = "CloudAppMaxRetryAttempts";
const char* kServerPortKey = "ServerPort";
const char* kVideoStreamingPortKey = "VideoStreamingPort";
const char* kAudioStreamingPortKey = "AudioStreamingPort";
@@ -318,6 +321,8 @@ const uint32_t kDefaultHubProtocolIndex = 0;
const uint32_t kDefaultHeartBeatTimeout = 0;
const uint16_t kDefaultMaxSupportedProtocolVersion = 5;
const uint16_t kDefautTransportManagerTCPPort = 12345;
+const uint16_t kDefaultCloudAppRetryTimeout = 1000;
+const uint16_t kDefaultCloudAppMaxRetryAttempts = 5;
const uint16_t kDefaultServerPort = 8087;
const uint16_t kDefaultVideoStreamingPort = 5050;
const uint16_t kDefaultAudioStreamingPort = 5080;
@@ -452,6 +457,8 @@ Profile::Profile()
, supported_diag_modes_()
, system_files_path_(kDefaultSystemFilesPath)
, transport_manager_tcp_adapter_port_(kDefautTransportManagerTCPPort)
+ , cloud_app_retry_timeout_(kDefaultCloudAppRetryTimeout)
+ , cloud_app_max_retry_attempts_(kDefaultCloudAppMaxRetryAttempts)
, tts_delimiter_(kDefaultTtsDelimiter)
, audio_data_stopped_timeout_(kDefaultAudioDataStoppedTimeout)
, video_data_stopped_timeout_(kDefaultVideoDataStoppedTimeout)
@@ -784,6 +791,14 @@ const std::string& Profile::transport_manager_tcp_adapter_network_interface()
return transport_manager_tcp_adapter_network_interface_;
}
+uint32_t Profile::cloud_app_retry_timeout() const {
+ return cloud_app_retry_timeout_;
+}
+
+uint16_t Profile::cloud_app_max_retry_attempts() const {
+ return cloud_app_max_retry_attempts_;
+}
+
const std::string& Profile::tts_delimiter() const {
return tts_delimiter_;
}
@@ -1769,6 +1784,24 @@ void Profile::UpdateValues() {
kTCPAdapterNetworkInterfaceKey,
kTransportManagerSection);
+ ReadUIntValue(&cloud_app_retry_timeout_,
+ kDefaultCloudAppRetryTimeout,
+ kCloudAppTransportSection,
+ kCloudAppRetryTimeoutKey);
+
+ LOG_UPDATED_VALUE(cloud_app_retry_timeout_,
+ kCloudAppRetryTimeoutKey,
+ kCloudAppTransportSection);
+
+ ReadUIntValue(&cloud_app_max_retry_attempts_,
+ kDefaultCloudAppMaxRetryAttempts,
+ kCloudAppTransportSection,
+ kCloudAppMaxRetryAttemptsKey);
+
+ LOG_UPDATED_VALUE(cloud_app_max_retry_attempts_,
+ kCloudAppMaxRetryAttemptsKey,
+ kCloudAppTransportSection);
+
// Event MQ
ReadStringValue(
&event_mq_name_, kDefaultEventMQ, kTransportManagerSection, kEventMQKey);
diff --git a/src/components/connection_handler/include/connection_handler/connection_handler_impl.h b/src/components/connection_handler/include/connection_handler/connection_handler_impl.h
index 1ab70ce702..899d17995c 100644
--- a/src/components/connection_handler/include/connection_handler/connection_handler_impl.h
+++ b/src/components/connection_handler/include/connection_handler/connection_handler_impl.h
@@ -120,6 +120,9 @@ class ConnectionHandlerImpl
void ConnectToAllDevices() OVERRIDE;
+ void AddCloudAppDevice(const std::string& endpoint,
+ const std::string& cloud_transport_type) OVERRIDE;
+
void StartTransportManager() OVERRIDE;
void OnDeviceListUpdated(
@@ -163,6 +166,14 @@ class ConnectionHandlerImpl
const transport_manager::SearchDeviceError& error) OVERRIDE;
/**
+ * \brief Notifies about pending connection.
+ *
+ * \param connection_id ID of new connection.
+ **/
+ void OnConnectionPending(
+ const transport_manager::DeviceInfo& device_info,
+ const transport_manager::ConnectionUID connection_id) OVERRIDE;
+ /**
* \brief Notifies about established connection.
*
* \param connection_id ID of new connection.
diff --git a/src/components/connection_handler/src/connection_handler_impl.cc b/src/components/connection_handler/src/connection_handler_impl.cc
index 478127c42a..9dc78613fc 100644
--- a/src/components/connection_handler/src/connection_handler_impl.cc
+++ b/src/components/connection_handler/src/connection_handler_impl.cc
@@ -142,6 +142,11 @@ void ConnectionHandlerImpl::OnDeviceAdded(
LOG4CXX_AUTO_TRACE(logger_);
auto handle = device_info.device_handle();
+ LOG4CXX_DEBUG(logger_,
+ "OnDeviceAdded!!!: " << handle << " " << device_info.name()
+ << " " << device_info.mac_address() << " "
+ << device_info.connection_type());
+
Device device(handle,
device_info.name(),
device_info.mac_address(),
@@ -244,11 +249,51 @@ void ConnectionHandlerImpl::OnScanDevicesFailed(
LOG4CXX_WARN(logger_, "Scan devices failed. " << error.text());
}
-void ConnectionHandlerImpl::OnConnectionEstablished(
+void ConnectionHandlerImpl::OnConnectionPending(
const transport_manager::DeviceInfo& device_info,
const transport_manager::ConnectionUID connection_id) {
LOG4CXX_AUTO_TRACE(logger_);
+ LOG4CXX_DEBUG(logger_,
+ "OnConnectionEstablished!!!: "
+ << device_info.device_handle() << " " << device_info.name()
+ << " " << device_info.mac_address() << " "
+ << device_info.connection_type());
+ DeviceMap::iterator it = device_list_.find(device_info.device_handle());
+ if (device_list_.end() == it) {
+ LOG4CXX_ERROR(logger_, "Unknown device!");
+ return;
+ }
+ LOG4CXX_DEBUG(logger_,
+ "Add Pending Connection #" << connection_id << " to the list.");
+
+ sync_primitives::AutoWriteLock lock(connection_list_lock_);
+ if (connection_list_.find(connection_id) == connection_list_.end()) {
+ Connection* connection =
+ new Connection(connection_id,
+ device_info.device_handle(),
+ this,
+ get_settings().heart_beat_timeout());
+
+ connection_list_.insert(
+ ConnectionList::value_type(connection_id, connection));
+ connection_handler::DeviceHandle device_id =
+ connection->connection_device_handle();
+
+ connection_handler_observer_->CreatePendingApplication(
+ connection_id, device_info, device_id);
+ }
+}
+
+void ConnectionHandlerImpl::OnConnectionEstablished(
+ const transport_manager::DeviceInfo& device_info,
+ const transport_manager::ConnectionUID connection_id) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ LOG4CXX_DEBUG(logger_,
+ "OnConnectionEstablished!!!: "
+ << device_info.device_handle() << " " << device_info.name()
+ << " " << device_info.mac_address() << " "
+ << device_info.connection_type());
DeviceMap::iterator it = device_list_.find(device_info.device_handle());
if (device_list_.end() == it) {
LOG4CXX_ERROR(logger_, "Unknown device!");
@@ -257,12 +302,14 @@ void ConnectionHandlerImpl::OnConnectionEstablished(
LOG4CXX_DEBUG(logger_,
"Add Connection #" << connection_id << " to the list.");
sync_primitives::AutoWriteLock lock(connection_list_lock_);
- connection_list_.insert(ConnectionList::value_type(
- connection_id,
- new Connection(connection_id,
- device_info.device_handle(),
- this,
- get_settings().heart_beat_timeout())));
+ if (connection_list_.find(connection_id) == connection_list_.end()) {
+ connection_list_.insert(ConnectionList::value_type(
+ connection_id,
+ new Connection(connection_id,
+ device_info.device_handle(),
+ this,
+ get_settings().heart_beat_timeout())));
+ }
}
void ConnectionHandlerImpl::OnConnectionFailed(
@@ -1267,6 +1314,11 @@ void ConnectionHandlerImpl::ConnectToAllDevices() {
}
}
+void ConnectionHandlerImpl::AddCloudAppDevice(
+ const std::string& endpoint, const std::string& cloud_transport_type) {
+ transport_manager_.AddCloudDevice(endpoint, cloud_transport_type);
+}
+
void ConnectionHandlerImpl::StartTransportManager() {
LOG4CXX_AUTO_TRACE(logger_);
transport_manager_.Visibility(true);
diff --git a/src/components/include/connection_handler/connection_handler.h b/src/components/include/connection_handler/connection_handler.h
index a50760b547..9ca9a8d144 100644
--- a/src/components/include/connection_handler/connection_handler.h
+++ b/src/components/include/connection_handler/connection_handler.h
@@ -93,6 +93,9 @@ class ConnectionHandler {
virtual void ConnectToAllDevices() = 0;
+ virtual void AddCloudAppDevice(const std::string& endpoint,
+ const std::string& cloud_transport_type) = 0;
+
/**
* @brief Close the connection revoked by Policy
* @param connection_key pair of connection and session id
diff --git a/src/components/include/connection_handler/connection_handler_observer.h b/src/components/include/connection_handler/connection_handler_observer.h
index 154a2a8e34..298f98803a 100644
--- a/src/components/include/connection_handler/connection_handler_observer.h
+++ b/src/components/include/connection_handler/connection_handler_observer.h
@@ -161,6 +161,11 @@ class ConnectionHandlerObserver {
*/
virtual void OnSecondaryTransportEndedCallback(const int32_t session_key) = 0;
+ virtual void CreatePendingApplication(
+ const transport_manager::ConnectionUID connection_id,
+ const transport_manager::DeviceInfo& device_info,
+ connection_handler::DeviceHandle device_id) = 0;
+
protected:
/**
* \brief Destructor
diff --git a/src/components/include/test/connection_handler/mock_connection_handler.h b/src/components/include/test/connection_handler/mock_connection_handler.h
index 2de3a0f9a7..cde835759f 100644
--- a/src/components/include/test/connection_handler/mock_connection_handler.h
+++ b/src/components/include/test/connection_handler/mock_connection_handler.h
@@ -63,6 +63,9 @@ class MockConnectionHandler : public connection_handler::ConnectionHandler {
MOCK_CONST_METHOD2(RunAppOnDevice,
void(const std::string&, const std::string&));
MOCK_METHOD0(ConnectToAllDevices, void());
+ MOCK_METHOD2(AddCloudAppDevice,
+ void(const std::string& endpoint,
+ const std::string& cloud_transport_type));
MOCK_METHOD1(CloseRevokedConnection, void(uint32_t connection_key));
MOCK_METHOD1(CloseConnection, void(ConnectionHandle connection_handle));
MOCK_METHOD1(GetConnectionSessionsCount, uint32_t(uint32_t connection_key));
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 a9e4349bec..2984b2e471 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
@@ -74,6 +74,10 @@ class MockConnectionHandlerObserver
const int32_t session_key));
MOCK_METHOD1(OnSecondaryTransportEndedCallback,
void(const int32_t session_key));
+ MOCK_METHOD3(CreatePendingApplication,
+ void(const transport_manager::ConnectionUID connection_id,
+ const transport_manager::DeviceInfo& device_info,
+ connection_handler::DeviceHandle device_id));
};
} // namespace connection_handler_test
diff --git a/src/components/include/test/transport_manager/mock_transport_manager.h b/src/components/include/test/transport_manager/mock_transport_manager.h
index cc8bd5ab85..e3f01fccb5 100644
--- a/src/components/include/test/transport_manager/mock_transport_manager.h
+++ b/src/components/include/test/transport_manager/mock_transport_manager.h
@@ -59,6 +59,9 @@ class MockTransportManager : public ::transport_manager::TransportManager,
MOCK_METHOD1(Init, int(resumption::LastState& last_state));
MOCK_METHOD0(Reinit, int());
MOCK_METHOD0(SearchDevices, int());
+ MOCK_METHOD2(AddCloudDevice,
+ void(const std::string& endpoint,
+ const std::string& cloud_transport_type));
MOCK_METHOD1(ConnectDevice, int(const DeviceHandle));
MOCK_METHOD1(DisconnectDevice, int(const DeviceHandle));
MOCK_METHOD1(Disconnect, int(const ConnectionUID));
diff --git a/src/components/include/test/transport_manager/mock_transport_manager_listener.h b/src/components/include/test/transport_manager/mock_transport_manager_listener.h
index 133dabe732..734651f455 100644
--- a/src/components/include/test/transport_manager/mock_transport_manager_listener.h
+++ b/src/components/include/test/transport_manager/mock_transport_manager_listener.h
@@ -55,6 +55,9 @@ class MockTransportManagerListener : public TransportManagerListener {
MOCK_METHOD1(OnDeviceRemoved, void(const DeviceInfo& device_info));
MOCK_METHOD0(OnScanDevicesFinished, void());
MOCK_METHOD1(OnScanDevicesFailed, void(const SearchDeviceError& error));
+ MOCK_METHOD2(OnConnectionPending,
+ void(const DeviceInfo& device_info,
+ const ConnectionUID connection_id));
MOCK_METHOD2(OnConnectionEstablished,
void(const DeviceInfo& device_info,
const ConnectionUID connection_id));
diff --git a/src/components/include/test/transport_manager/mock_transport_manager_settings.h b/src/components/include/test/transport_manager/mock_transport_manager_settings.h
index 3e7c8f36f7..bed0d5e6e6 100644
--- a/src/components/include/test/transport_manager/mock_transport_manager_settings.h
+++ b/src/components/include/test/transport_manager/mock_transport_manager_settings.h
@@ -63,6 +63,8 @@ class MockTransportManagerSettings
MOCK_CONST_METHOD0(app_transport_change_timer_addition, uint32_t());
MOCK_CONST_METHOD0(transport_manager_tcp_adapter_network_interface,
std::string&());
+ MOCK_CONST_METHOD0(cloud_app_retry_timeout, uint32_t());
+ MOCK_CONST_METHOD0(cloud_app_max_retry_attempts, uint16_t());
};
} // namespace transport_manager_test
diff --git a/src/components/include/test/transport_manager/transport_adapter/mock_transport_adapter.h b/src/components/include/test/transport_manager/transport_adapter/mock_transport_adapter.h
index eff0abdcd3..0be4da1063 100644
--- a/src/components/include/test/transport_manager/transport_adapter/mock_transport_adapter.h
+++ b/src/components/include/test/transport_manager/transport_adapter/mock_transport_adapter.h
@@ -105,6 +105,8 @@ class MockTransportAdapter
transport_manager::SwitchableDevices());
MOCK_CONST_METHOD0(GetTransportConfiguration,
transport_manager::transport_adapter::TransportConfig());
+ MOCK_METHOD1(CreateDevice, void(const std::string& uid));
+
#ifdef TELEMETRY_MONITOR
MOCK_METHOD0(GetTelemetryObserver,
::transport_manager::TMTelemetryObserver*());
diff --git a/src/components/include/transport_manager/transport_adapter/transport_adapter.h b/src/components/include/transport_manager/transport_adapter/transport_adapter.h
index ebbf7dae28..aae4a8b569 100644
--- a/src/components/include/transport_manager/transport_adapter/transport_adapter.h
+++ b/src/components/include/transport_manager/transport_adapter/transport_adapter.h
@@ -64,6 +64,7 @@ enum DeviceType {
IOS_BT,
IOS_USB,
TCP,
+ CLOUD_WEBSOCKET,
IOS_USB_HOST_MODE,
IOS_USB_DEVICE_MODE,
IOS_CARPLAY_WIRELESS, // running on iAP over Carplay wireless transport
@@ -327,6 +328,8 @@ class TransportAdapter {
*/
virtual TransportConfig GetTransportConfiguration() const = 0;
+ virtual void CreateDevice(const std::string& uid) = 0;
+
#ifdef TELEMETRY_MONITOR
/**
* @brief Return Time metric observer
diff --git a/src/components/include/transport_manager/transport_adapter/transport_adapter_event.h b/src/components/include/transport_manager/transport_adapter/transport_adapter_event.h
index fd1d693067..921562333b 100644
--- a/src/components/include/transport_manager/transport_adapter/transport_adapter_event.h
+++ b/src/components/include/transport_manager/transport_adapter/transport_adapter_event.h
@@ -58,7 +58,8 @@ enum class EventTypeEnum {
ON_COMMUNICATION_ERROR,
ON_UNEXPECTED_DISCONNECT,
ON_TRANSPORT_SWITCH_REQUESTED,
- ON_TRANSPORT_CONFIG_UPDATED
+ ON_TRANSPORT_CONFIG_UPDATED,
+ ON_CONNECT_PENDING
};
class TransportAdapterEvent {
diff --git a/src/components/include/transport_manager/transport_manager.h b/src/components/include/transport_manager/transport_manager.h
index 0847886c46..b5dfa3671b 100644
--- a/src/components/include/transport_manager/transport_manager.h
+++ b/src/components/include/transport_manager/transport_manager.h
@@ -75,6 +75,9 @@ class TransportManager {
**/
virtual int SearchDevices() = 0;
+ virtual void AddCloudDevice(const std::string& endpoint,
+ const std::string& cloud_transport_type) = 0;
+
/**
* @brief Connect to all applications discovered on device.
*
diff --git a/src/components/include/transport_manager/transport_manager_listener.h b/src/components/include/transport_manager/transport_manager_listener.h
index 6c3f6e2eaa..7da4bcc2f5 100644
--- a/src/components/include/transport_manager/transport_manager_listener.h
+++ b/src/components/include/transport_manager/transport_manager_listener.h
@@ -101,6 +101,14 @@ class TransportManagerListener {
virtual void OnScanDevicesFailed(const SearchDeviceError& error) = 0;
/**
+ * @brief Reaction to the event, when connection is pending.
+ *
+ * @param devcie_info Variable that hold information about device.
+ * @param connection_id connection unique identifier.
+ */
+ virtual void OnConnectionPending(const DeviceInfo& device_info,
+ const ConnectionUID connection_id) = 0;
+ /**
* @brief Reaction to the event, when connection is established.
*
* @param devcie_info Variable that hold information about device.
diff --git a/src/components/include/transport_manager/transport_manager_listener_empty.h b/src/components/include/transport_manager/transport_manager_listener_empty.h
index 08b2b77c30..c0a713f38e 100644
--- a/src/components/include/transport_manager/transport_manager_listener_empty.h
+++ b/src/components/include/transport_manager/transport_manager_listener_empty.h
@@ -99,6 +99,15 @@ class TransportManagerListenerEmpty : public TransportManagerListener {
void OnScanDevicesFailed(const SearchDeviceError& error) OVERRIDE {}
/**
+ * @brief Reaction to the event, when connection is pending.
+ *
+ * @param devcie_info Variable that hold information about device.
+ * @param connection_id connection unique identifier.
+ */
+ void OnConnectionPending(const DeviceInfo& device_info,
+ const ConnectionUID connection_id) OVERRIDE {}
+
+ /**
* @brief Reaction to the event, when connection is established.
*
* @param devcie_info Variable that hold information about device.
diff --git a/src/components/include/transport_manager/transport_manager_settings.h b/src/components/include/transport_manager/transport_manager_settings.h
index 3912bbe747..cbc1516c29 100644
--- a/src/components/include/transport_manager/transport_manager_settings.h
+++ b/src/components/include/transport_manager/transport_manager_settings.h
@@ -69,6 +69,16 @@ class TransportManagerSettings : public TransportManagerMMESettings {
*/
virtual const std::string& transport_manager_tcp_adapter_network_interface()
const = 0;
+
+ /**
+ * @brief Returns retry timeout for cloud app connections
+ */
+ virtual uint32_t cloud_app_retry_timeout() const = 0;
+
+ /**
+ * @brief Returns maximum retry attempts for cloud app connections
+ */
+ virtual uint16_t cloud_app_max_retry_attempts() const = 0;
};
} // namespace transport_manager
#endif // SRC_COMPONENTS_INCLUDE_TRANSPORT_MANAGER_TRANSPORT_MANAGER_SETTINGS_H_
diff --git a/src/components/interfaces/HMI_API.xml b/src/components/interfaces/HMI_API.xml
index 2d256423bd..a11cfbfd8a 100644
--- a/src/components/interfaces/HMI_API.xml
+++ b/src/components/interfaces/HMI_API.xml
@@ -72,6 +72,7 @@
<element name="USB_IOS"/>
<element name="USB_AOA"/>
<element name="WIFI"/>
+ <element name="CLOUD_WEBSOCKET"/>
</enum>
<enum name="ButtonName">
diff --git a/src/components/protocol_handler/include/protocol_handler/protocol_handler_impl.h b/src/components/protocol_handler/include/protocol_handler/protocol_handler_impl.h
index 3e7d64e9d2..ccf6082a18 100644
--- a/src/components/protocol_handler/include/protocol_handler/protocol_handler_impl.h
+++ b/src/components/protocol_handler/include/protocol_handler/protocol_handler_impl.h
@@ -512,6 +512,10 @@ class ProtocolHandlerImpl
void OnTMMessageSendFailed(const transport_manager::DataSendError& error,
const RawMessagePtr message) OVERRIDE;
+ void OnConnectionPending(
+ const transport_manager::DeviceInfo& device_info,
+ const transport_manager::ConnectionUID connection_id) OVERRIDE;
+
void OnConnectionEstablished(
const transport_manager::DeviceInfo& device_info,
const transport_manager::ConnectionUID connection_id) OVERRIDE;
diff --git a/src/components/protocol_handler/src/protocol_handler_impl.cc b/src/components/protocol_handler/src/protocol_handler_impl.cc
index d03030b747..ee2dc73780 100644
--- a/src/components/protocol_handler/src/protocol_handler_impl.cc
+++ b/src/components/protocol_handler/src/protocol_handler_impl.cc
@@ -1087,6 +1087,10 @@ void ProtocolHandlerImpl::OnTMMessageSendFailed(
<< "Error_text: " << error.text());
}
+void ProtocolHandlerImpl::OnConnectionPending(
+ const transport_manager::DeviceInfo& device_info,
+ const transport_manager::ConnectionUID connection_id) {}
+
void ProtocolHandlerImpl::OnConnectionEstablished(
const transport_manager::DeviceInfo& device_info,
const transport_manager::ConnectionUID connection_id) {
diff --git a/src/components/transport_manager/CMakeLists.txt b/src/components/transport_manager/CMakeLists.txt
index 2f734b3a05..286e62b795 100644
--- a/src/components/transport_manager/CMakeLists.txt
+++ b/src/components/transport_manager/CMakeLists.txt
@@ -72,6 +72,11 @@ else()
)
endif()
+if(BUILD_CLOUD_APP_SUPPORT)
+ GET_PROPERTY(BOOST_LIBS_DIRECTORY GLOBAL PROPERTY GLOBAL_BOOST_LIBS)
+ list(APPEND LIBRARIES boost_system boost_regex -L${BOOST_LIBS_DIRECTORY})
+endif()
+
if(BUILD_USB_SUPPORT)
if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
set(EXCLUDE_PATHS
@@ -129,3 +134,4 @@ endif()
if(BUILD_TESTS)
add_subdirectory(test)
endif()
+
diff --git a/src/components/transport_manager/include/transport_manager/cloud/cloud_device.h b/src/components/transport_manager/include/transport_manager/cloud/cloud_device.h
new file mode 100644
index 0000000000..47a82e7921
--- /dev/null
+++ b/src/components/transport_manager/include/transport_manager/cloud/cloud_device.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2018, Livio
+ * 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.
+ */
+
+/**
+ * \file Cloud_device.h
+ * \brief CloudDevice class header file.
+ */
+
+#ifndef SRC_COMPONENTS_TRANSPORT_MANAGER_INCLUDE_TRANSPORT_MANAGER_CLOUD_CLOUD_DEVICE_H_
+#define SRC_COMPONENTS_TRANSPORT_MANAGER_INCLUDE_TRANSPORT_MANAGER_CLOUD_CLOUD_DEVICE_H_
+
+#include "transport_manager/transport_adapter/device.h"
+
+namespace transport_manager {
+namespace transport_adapter {
+
+class CloudDevice : public Device {
+ public:
+ CloudDevice(std::string& host, std::string& port, std::string& name);
+
+ virtual const std::string& GetHost() const;
+
+ virtual const std::string& GetPort() const;
+
+ protected:
+ virtual bool IsSameAs(const Device* other_device) const;
+
+ virtual ApplicationList GetApplicationList() const;
+
+ private:
+ const std::string host_;
+ const std::string port_;
+};
+
+} // namespace transport_adapter
+} // namespace transport_manager
+
+#endif // SRC_COMPONENTS_TRANSPORT_MANAGER_INCLUDE_TRANSPORT_MANAGER_CLOUD_CLOUD_DEVICE_H_
diff --git a/src/components/transport_manager/include/transport_manager/cloud/cloud_websocket_connection_factory.h b/src/components/transport_manager/include/transport_manager/cloud/cloud_websocket_connection_factory.h
new file mode 100644
index 0000000000..ef1754a6e7
--- /dev/null
+++ b/src/components/transport_manager/include/transport_manager/cloud/cloud_websocket_connection_factory.h
@@ -0,0 +1,98 @@
+/*
+ * \file cloud_websocket_connection_factory.h
+ * \brief CloudWebsocketConnectionFactory class header file.
+ *
+ * Copyright (c) 2018, Livio
+ * 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_CLOUD_CLOUD_WEBSOCKET_CONNECTION_FACTORY_H_
+#define SRC_COMPONENTS_TRANSPORT_MANAGER_INCLUDE_TRANSPORT_MANAGER_CLOUD_CLOUD_WEBSOCKET_CONNECTION_FACTORY_H_
+
+#include "transport_manager/transport_adapter/server_connection_factory.h"
+
+namespace transport_manager {
+namespace transport_adapter {
+
+class TransportAdapterController;
+
+/**
+ * @brief Create connections.
+ */
+class CloudWebsocketConnectionFactory : public ServerConnectionFactory {
+ public:
+ /**
+ * @brief Constructor.
+ *
+ * @param controller Pointer to the device adapter controller.
+ */
+ CloudWebsocketConnectionFactory(TransportAdapterController* controller);
+
+ protected:
+ /**
+ * @brief Start cloud websocket connection factory.
+ */
+ virtual TransportAdapter::Error Init();
+
+ /**
+ * @brief Create cloud boost websocket connection.
+ *
+ * @param device_uid Device unique identifier.
+ * @param ap_handle Handle of application.
+ */
+ virtual TransportAdapter::Error CreateConnection(
+ const DeviceUID& device_uid, const ApplicationHandle& app_handle);
+
+ /**
+ * @brief
+ */
+ virtual void Terminate();
+
+ /**
+ * @brief Check for initialization.
+ *
+ * @return true - initialized.
+ * false - not initialized.
+ */
+ virtual bool IsInitialised() const;
+
+ /**
+ * @brief Destructor.
+ */
+ virtual ~CloudWebsocketConnectionFactory();
+
+ private:
+ TransportAdapterController* controller_;
+};
+
+} // namespace transport_adapter
+} // namespace transport_manager
+
+#endif // SRC_COMPONENTS_TRANSPORT_MANAGER_INCLUDE_TRANSPORT_MANAGER_CLOUD_CLOUD_WEBSOCKET_CONNECTION_FACTORY_H_
diff --git a/src/components/transport_manager/include/transport_manager/cloud/cloud_websocket_transport_adapter.h b/src/components/transport_manager/include/transport_manager/cloud/cloud_websocket_transport_adapter.h
new file mode 100644
index 0000000000..d52e4b307d
--- /dev/null
+++ b/src/components/transport_manager/include/transport_manager/cloud/cloud_websocket_transport_adapter.h
@@ -0,0 +1,89 @@
+/*
+ * \file cloud_websocket_transport_adapter.h
+ * \brief Cloud Websocket Transport Adapterclass header file.
+ *
+ * Copyright (c) 2018, Livio
+ * 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_CLOUD_CLOUD_WEBSOCKET_TRANSPORT_ADAPTER_H_
+#define SRC_COMPONENTS_TRANSPORT_MANAGER_INCLUDE_TRANSPORT_MANAGER_CLOUD_CLOUD_WEBSOCKET_TRANSPORT_ADAPTER_H_
+
+#include "transport_manager/transport_adapter/transport_adapter_impl.h"
+
+namespace transport_manager {
+namespace transport_adapter {
+
+/**
+ * @brief Cloud transport adapter that uses websockets.
+ */
+class CloudWebsocketTransportAdapter : public TransportAdapterImpl {
+ public:
+ /**
+ * @brief Constructor.
+ */
+ explicit CloudWebsocketTransportAdapter(
+ resumption::LastState& last_state,
+ const TransportManagerSettings& settings);
+
+ /**
+ * @brief Destructor.
+ */
+ virtual ~CloudWebsocketTransportAdapter();
+
+ protected:
+ /**
+ * @brief Return type of device.
+ *
+ * @return String with device type.
+ */
+ virtual DeviceType GetDeviceType() const;
+
+ /**
+ * @brief Store adapter state in last state singleton
+ */
+ virtual void Store() const;
+
+ /**
+ * @brief Restore adapter state from last state singleton
+ *
+ * @return True on success false otherwise
+ */
+ virtual bool Restore();
+
+ void CreateDevice(const std::string& uid) OVERRIDE;
+
+ private:
+};
+
+} // namespace transport_adapter
+} // namespace transport_manager
+
+#endif // SRC_COMPONENTS_TRANSPORT_MANAGER_INCLUDE_TRANSPORT_MANAGER_TCP_TCP_TRANSPORT_ADAPTER_H_
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
new file mode 100644
index 0000000000..da3a80e1b2
--- /dev/null
+++ b/src/components/transport_manager/include/transport_manager/cloud/websocket_client_connection.h
@@ -0,0 +1,178 @@
+/*
+ * \file websocket_client_connection.h
+ * \brief WebsocketClientConnection class header file.
+ *
+ * Copyright (c) 2018, Livio
+ * 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_CLOUD_WEBSOCKET_CLIENT_CONNECTION_H_
+#define SRC_COMPONENTS_TRANSPORT_MANAGER_INCLUDE_TRANSPORT_MANAGER_CLOUD_WEBSOCKET_CLIENT_CONNECTION_H_
+
+#include <boost/beast/core.hpp>
+#include <boost/beast/websocket.hpp>
+#include <boost/beast/websocket/ssl.hpp>
+#include <boost/asio/connect.hpp>
+#include <boost/asio/ip/tcp.hpp>
+#include <boost/asio/ssl/stream.hpp>
+#include <cstdlib>
+#include <functional>
+#include <iostream>
+#include <memory>
+#include <string>
+#include <thread>
+#include "transport_manager/transport_adapter/connection.h"
+#include "utils/threads/thread.h"
+#include "utils/threads/message_loop_thread.h"
+#include "utils/message_queue.h"
+
+using tcp = boost::asio::ip::tcp; // from <boost/asio/ip/tcp.hpp>
+namespace ssl = boost::asio::ssl; // from <boost/asio/ssl.hpp>
+namespace websocket =
+ boost::beast::websocket; // from <boost/beast/websocket.hpp>
+using ::utils::MessageQueue;
+
+typedef std::queue<protocol_handler::RawMessagePtr> AsyncQueue;
+typedef protocol_handler::RawMessagePtr Message;
+
+namespace transport_manager {
+namespace transport_adapter {
+
+class TransportAdapterController;
+
+/**
+ * @brief Class responsible for communication over bluetooth sockets.
+ */
+class WebsocketClientConnection
+ : public std::enable_shared_from_this<WebsocketClientConnection>,
+ public Connection {
+ public:
+ /**
+ * @brief Constructor.
+ *
+ * @param device_uid Device unique identifier.
+ * @param app_handle Handle of device.
+ * @param controller Pointer to the device adapter controller.
+ */
+ WebsocketClientConnection(const DeviceUID& device_uid,
+ const ApplicationHandle& app_handle,
+ TransportAdapterController* controller);
+
+ /**
+ * @brief Destructor.
+ */
+ virtual ~WebsocketClientConnection();
+
+ /**
+ * @brief Check if we can start the connection attempt and establish
+ *connection status.
+ *
+ * @param error contains information of any error that occurred during
+ *connection attempt.
+ *
+ * @return result that states whether we successfully connected or not.
+ */
+ TransportAdapter::Error Start();
+
+ /**
+ * @brief Send data frame.
+ *
+ * @param message Smart pointer to the raw message.
+ *
+ * @return Error Information about possible reason of sending data failure.
+ */
+ TransportAdapter::Error SendData(::protocol_handler::RawMessagePtr message);
+
+ /**
+ * @brief Disconnect the current connection.
+ *
+ * @return Error Information about possible reason of Disconnect failure.
+ */
+ TransportAdapter::Error Disconnect();
+
+ void Shutdown();
+
+ void Recv(boost::system::error_code ec);
+
+ void OnRead(boost::system::error_code ec, std::size_t bytes_transferred);
+
+ private:
+ TransportAdapterController* controller_;
+ boost::asio::io_context ioc_;
+ tcp::resolver resolver_;
+ websocket::stream<tcp::socket> ws_;
+ boost::beast::flat_buffer buffer_;
+ std::string host_;
+ std::string text_;
+
+ std::atomic_bool shutdown_;
+
+ typedef std::queue<protocol_handler::RawMessagePtr> FrameQueue;
+ FrameQueue frames_to_send_;
+ mutable sync_primitives::Lock frames_to_send_mutex_;
+
+ MessageQueue<Message, AsyncQueue> message_queue_;
+
+ class LoopThreadDelegate : public threads::ThreadDelegate {
+ public:
+ LoopThreadDelegate(MessageQueue<Message, AsyncQueue>* message_queue,
+ WebsocketClientConnection* handler);
+
+ virtual void threadMain() OVERRIDE;
+ virtual void exitThreadMain() OVERRIDE;
+
+ void OnWrite();
+
+ void SetShutdown();
+
+ private:
+ void DrainQueue();
+ MessageQueue<Message, AsyncQueue>& message_queue_;
+ WebsocketClientConnection& handler_;
+ sync_primitives::Lock queue_lock_;
+ sync_primitives::ConditionalVariable queue_new_items_;
+ std::atomic_bool write_pending_;
+ std::atomic_bool shutdown_;
+
+ sync_primitives::Lock write_lock_;
+ };
+
+ LoopThreadDelegate* thread_delegate_;
+ threads::Thread* write_thread_;
+ std::thread io_service_thread_;
+
+ const DeviceUID device_uid_;
+ const ApplicationHandle app_handle_;
+};
+
+} // namespace transport_adapter
+} // namespace transport_manager
+
+#endif // SRC_COMPONENTS_TRANSPORT_MANAGER_INCLUDE_TRANSPORT_MANAGER_BLUETOOTH_BLUETOOTH_SOCKET_CONNECTION_H_
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 69d76b4b2b..6d97a55a70 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
@@ -100,6 +100,16 @@ class TransportAdapterController {
const ApplicationHandle& app_handle) = 0;
/**
+ * @brief Set state of specified connection - PENDING and launch
+ *OnConnectPending event in device adapter listener.
+ *
+ * @param devcie_handle Device unique identifier.
+ * @param app_handle Handle of application.
+ */
+ virtual void ConnectPending(const DeviceUID& device_handle,
+ const ApplicationHandle& app_handle) = 0;
+
+ /**
* @brief Make state of specified connection - ESTABLISHED and launch
*OnConnectDone event in device adapter listener.
*
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 078f93b32f..0af1f2b614 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
@@ -306,6 +306,16 @@ class TransportAdapterImpl : public TransportAdapter,
const CommunicationError& error) OVERRIDE;
/**
+ * @brief Set state of specified connection - PENDING and launch
+ *OnConnectPending event in device adapter listener.
+ *
+ * @param devcie_handle Device unique identifier.
+ * @param app_handle Handle of application.
+ */
+ void ConnectPending(const DeviceUID& device_handle,
+ const ApplicationHandle& app_handle) OVERRIDE;
+
+ /**
* @brief Set state of specified connection - ESTABLISHED and launch
*OnConnectDone event in device adapter listener.
*
@@ -434,6 +444,10 @@ class TransportAdapterImpl : public TransportAdapter,
return TransportConfig();
}
+ void CreateDevice(const std::string& uid) OVERRIDE {
+ return;
+ }
+
/**
* @brief Return name of device.
*
@@ -564,7 +578,7 @@ class TransportAdapterImpl : public TransportAdapter,
ConnectionSPtr connection;
DeviceUID device_id;
ApplicationHandle app_handle;
- enum { NEW, ESTABLISHED, FINALISING } state;
+ enum { NEW, ESTABLISHED, FINALISING, PENDING, RETRY } state;
};
/**
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 4606bac2d4..b0368869e7 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
@@ -93,6 +93,19 @@ class TransportAdapterListener {
/**
* @brief Search specified device adapter in the container of shared pointers
+ * to device adapters to be sure it is available,
+ * launch event ON_CONNECT_PENDING in transport manager.
+ *
+ * @param device_adater Pointer to the device adapter.
+ * @param device_handle Device unique identifier.
+ * @param app_id Handle of application.
+ */
+ virtual void OnConnectPending(const TransportAdapter* adapter,
+ const DeviceUID& device_handle,
+ const ApplicationHandle& app_id) = 0;
+
+ /**
+ * @brief Search specified device adapter in the container of shared pointers
*to device adapters to be sure it is available,
* launch event ON_CONNECT_DONE in transport manager.
*
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 a744400279..76271229ad 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
@@ -89,6 +89,19 @@ class TransportAdapterListenerImpl
/**
* @brief Search specified device adapter in the container of shared pointers
+ * to device adapters to be sure it is available,
+ * launch event ON_CONNECT_PENDING in transport manager.
+ *
+ * @param device_adater Pointer to the device adapter.
+ * @param device_handle Device unique identifier.
+ * @param app_id Handle of application.
+ */
+ virtual void OnConnectPending(const TransportAdapter* adapter,
+ const DeviceUID& device_handle,
+ const ApplicationHandle& app_id);
+
+ /**
+ * @brief Search specified device adapter in the container of shared pointers
*to device adapters to be sure it is available,
* launch event ON_CONNECT_DONE in 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 c1df49f91b..dcb3b6922c 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
@@ -140,6 +140,9 @@ class TransportManagerImpl
**/
int SearchDevices() OVERRIDE;
+ void AddCloudDevice(const std::string& endpoint,
+ const std::string& cloud_transport_type) OVERRIDE;
+
/**
* @brief Connect to all applications discovered on device.
*
diff --git a/src/components/transport_manager/src/cloud/cloud_device.cc b/src/components/transport_manager/src/cloud/cloud_device.cc
new file mode 100644
index 0000000000..90a485c069
--- /dev/null
+++ b/src/components/transport_manager/src/cloud/cloud_device.cc
@@ -0,0 +1,75 @@
+/*
+ *
+ * Copyright (c) 2018, Livio
+ * 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/cloud/cloud_device.h"
+
+#include "utils/logger.h"
+
+namespace transport_manager {
+namespace transport_adapter {
+CREATE_LOGGERPTR_GLOBAL(logger_, "TransportManager")
+
+CloudDevice::CloudDevice(std::string& host,
+ std::string& port,
+ std::string& name)
+ : Device(name, std::string(name)), host_(host), port_(port) {}
+
+bool CloudDevice::IsSameAs(const Device* other) const {
+ LOG4CXX_TRACE(logger_, "enter. device: " << other);
+
+ const CloudDevice* other_cloud_device =
+ dynamic_cast<const CloudDevice*>(other);
+
+ if (host_ != other_cloud_device->GetHost()) {
+ return false;
+ }
+ if (port_ != other_cloud_device->GetPort()) {
+ return false;
+ }
+ return true;
+}
+
+ApplicationList CloudDevice::GetApplicationList() const {
+ return ApplicationList{100};
+}
+
+const std::string& CloudDevice::GetHost() const {
+ return host_;
+}
+
+const std::string& CloudDevice::GetPort() const {
+ return port_;
+}
+
+} // namespace transport_adapter
+} // namespace transport_manager
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
new file mode 100644
index 0000000000..cdc27ed8ef
--- /dev/null
+++ b/src/components/transport_manager/src/cloud/cloud_websocket_connection_factory.cc
@@ -0,0 +1,81 @@
+/*
+ * \file cloud_websocket_connection_factory.cc
+ * \brief CloudWebsocketConnectionFactory class source file.
+ *
+ * Copyright (c) 2018, Livio
+ * 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/transport_adapter/transport_adapter_controller.h"
+#include "transport_manager/cloud/cloud_websocket_connection_factory.h"
+#include "transport_manager/cloud/websocket_client_connection.h"
+#include "utils/logger.h"
+
+#include "transport_manager/cloud/cloud_device.h"
+
+namespace transport_manager {
+namespace transport_adapter {
+
+CREATE_LOGGERPTR_GLOBAL(logger_, "TransportManager")
+
+CloudWebsocketConnectionFactory::CloudWebsocketConnectionFactory(
+ TransportAdapterController* controller)
+ : controller_(controller) {}
+
+TransportAdapter::Error CloudWebsocketConnectionFactory::Init() {
+ return TransportAdapter::OK;
+}
+
+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();
+ if (TransportAdapter::OK != error) {
+ LOG4CXX_ERROR(
+ logger_,
+ "Cloud Websocket connection::Start() failed with error: " << error);
+ }
+ return error;
+}
+
+void CloudWebsocketConnectionFactory::Terminate() {}
+
+bool CloudWebsocketConnectionFactory::IsInitialised() const {
+ return true;
+}
+
+CloudWebsocketConnectionFactory::~CloudWebsocketConnectionFactory() {}
+
+} // namespace transport_adapter
+} // namespace transport_manager
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
new file mode 100644
index 0000000000..24efdfb2a4
--- /dev/null
+++ b/src/components/transport_manager/src/cloud/cloud_websocket_transport_adapter.cc
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2018, Livio
+ * 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/cloud/cloud_websocket_transport_adapter.h"
+#include "transport_manager/cloud/cloud_websocket_connection_factory.h"
+
+#include "transport_manager/cloud/cloud_device.h"
+#include "transport_manager/cloud/websocket_client_connection.h"
+
+#include <boost/regex.hpp>
+
+namespace transport_manager {
+namespace transport_adapter {
+
+CREATE_LOGGERPTR_GLOBAL(logger_, "TransportManager")
+
+CloudWebsocketTransportAdapter::CloudWebsocketTransportAdapter(
+ resumption::LastState& last_state, const TransportManagerSettings& settings)
+ : TransportAdapterImpl(NULL,
+ new CloudWebsocketConnectionFactory(this),
+ NULL,
+ last_state,
+ settings) {}
+
+CloudWebsocketTransportAdapter::~CloudWebsocketTransportAdapter() {}
+
+DeviceType CloudWebsocketTransportAdapter::GetDeviceType() const {
+ return CLOUD_WEBSOCKET;
+}
+
+void CloudWebsocketTransportAdapter::Store() const {}
+
+bool CloudWebsocketTransportAdapter::Restore() {
+ return true;
+}
+
+void CloudWebsocketTransportAdapter::CreateDevice(const std::string& uid) {
+ boost::regex pattern(
+ "(wss?):\\/\\/([A-Z\\d\\.-]{2,})\\.?([A-Z]{2,})?(:\\d{2,4})\\/",
+ boost::regex::icase);
+ std::string str = uid;
+ if (!boost::regex_match(str, pattern)) {
+ LOG4CXX_DEBUG(logger_, "Invalid Endpoint: " << uid);
+ return;
+ }
+
+ LOG4CXX_DEBUG(logger_, "Valid Endpoint: " << uid);
+ std::size_t pos = uid.find(":");
+ pos = uid.find(":", pos + 1);
+ // std::size_t size = uid.length();
+ std::string host = uid.substr(0, pos);
+ std::string port = uid.substr(pos + 1);
+ std::string device_id = uid;
+
+ LOG4CXX_DEBUG(logger_,
+ "Creating Cloud Device For Host: " << host
+ << " and Port: " << port);
+
+ auto cloud_device = std::make_shared<CloudDevice>(host, port, device_id);
+
+ DeviceVector devices{cloud_device};
+
+ SearchDeviceDone(devices);
+
+ // Create connection object, do not start until app is activated
+ std::shared_ptr<WebsocketClientConnection> connection =
+ std::make_shared<WebsocketClientConnection>(uid, 0, this);
+
+ ConnectionCreated(connection, uid, 0);
+ ConnectPending(uid, 0);
+
+ return;
+}
+}
+} \ No newline at end of file
diff --git a/src/components/transport_manager/src/cloud/websocket_client_connection.cc b/src/components/transport_manager/src/cloud/websocket_client_connection.cc
new file mode 100644
index 0000000000..4f585c8efb
--- /dev/null
+++ b/src/components/transport_manager/src/cloud/websocket_client_connection.cc
@@ -0,0 +1,244 @@
+/*
+ *
+ * Copyright (c) 2018, Livio
+ * 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/cloud/websocket_client_connection.h"
+#include "transport_manager/cloud/cloud_device.h"
+
+#include "transport_manager/transport_adapter/transport_adapter_controller.h"
+
+#include "utils/logger.h"
+
+namespace transport_manager {
+namespace transport_adapter {
+CREATE_LOGGERPTR_GLOBAL(logger_, "TransportManager")
+
+WebsocketClientConnection::WebsocketClientConnection(
+ const DeviceUID& device_uid,
+ const ApplicationHandle& app_handle,
+ TransportAdapterController* controller)
+ : controller_(controller)
+ , resolver_(ioc_)
+ , ws_(ioc_)
+ , shutdown_(false)
+ , thread_delegate_(new LoopThreadDelegate(&message_queue_, this))
+ , write_thread_(threads::CreateThread("WS Async Send", thread_delegate_))
+ , device_uid_(device_uid)
+ , app_handle_(app_handle) {}
+
+WebsocketClientConnection::~WebsocketClientConnection() {
+ ioc_.stop();
+ if (io_service_thread_.joinable()) {
+ io_service_thread_.join();
+ }
+}
+
+TransportAdapter::Error WebsocketClientConnection::Start() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ DeviceSptr device = controller_->FindDevice(device_uid_);
+ CloudDevice* cloud_device = static_cast<CloudDevice*>(device.get());
+ auto const host = cloud_device->GetHost();
+ auto const port = cloud_device->GetPort();
+ boost::system::error_code ec;
+ auto const results = resolver_.resolve(host, port, ec);
+ 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);
+ if (ec) {
+ std::string str_err = "ErrorMessage: " + ec.message();
+ LOG4CXX_ERROR(logger_,
+ "Could not connect to websocket: " << host << ":" << port);
+ LOG4CXX_ERROR(logger_, str_err);
+ Shutdown();
+ return TransportAdapter::FAIL;
+ }
+ ws_.handshake(host, "/", ec);
+ if (ec) {
+ std::string str_err = "ErrorMessage: " + ec.message();
+ LOG4CXX_ERROR(logger_,
+ "Could not complete handshake with host/port: " << host << ":"
+ << port);
+ LOG4CXX_ERROR(logger_, str_err);
+ Shutdown();
+ return TransportAdapter::FAIL;
+ }
+ ws_.binary(true);
+ write_thread_->start(threads::ThreadOptions());
+ controller_->ConnectDone(device_uid_, app_handle_);
+
+ // Start async read
+ ws_.async_read(buffer_,
+ std::bind(&WebsocketClientConnection::OnRead,
+ this,
+ 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");
+ });
+
+ LOG4CXX_DEBUG(logger_,
+ "Successfully started websocket connection @: " << host << ":"
+ << port);
+
+ return TransportAdapter::OK;
+}
+
+void WebsocketClientConnection::Recv(boost::system::error_code ec) {
+ if (shutdown_) {
+ return;
+ }
+
+ if (ec) {
+ std::string str_err = "ErrorMessage: " + ec.message();
+ LOG4CXX_ERROR(logger_, str_err);
+ Shutdown();
+ return;
+ }
+
+ ws_.async_read(buffer_,
+ std::bind(&WebsocketClientConnection::OnRead,
+ this,
+ std::placeholders::_1,
+ std::placeholders::_2));
+}
+
+void WebsocketClientConnection::OnRead(boost::system::error_code ec,
+ std::size_t bytes_transferred) {
+ boost::ignore_unused(bytes_transferred);
+ if (ec) {
+ std::string str_err = "ErrorMessage: " + ec.message();
+ LOG4CXX_ERROR(logger_, str_err);
+ 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*>(
+ boost::beast::buffers_front(buffer_.data()));
+
+ ::protocol_handler::RawMessagePtr frame(
+ new protocol_handler::RawMessage(0, 0, data, size));
+
+ controller_->DataReceiveDone(device_uid_, app_handle_, frame);
+
+ buffer_.consume(buffer_.size());
+ Recv(ec);
+}
+
+TransportAdapter::Error WebsocketClientConnection::SendData(
+ ::protocol_handler::RawMessagePtr message) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ sync_primitives::AutoLock auto_lock(frames_to_send_mutex_);
+ message_queue_.push(message);
+ return TransportAdapter::OK;
+}
+
+TransportAdapter::Error WebsocketClientConnection::Disconnect() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ Shutdown();
+ return TransportAdapter::OK;
+}
+
+void WebsocketClientConnection::Shutdown() {
+ shutdown_ = true;
+
+ if (thread_delegate_) {
+ thread_delegate_->SetShutdown();
+ write_thread_->join();
+ delete thread_delegate_;
+ }
+ if (buffer_.size()) {
+ buffer_.consume(buffer_.size());
+ }
+}
+
+WebsocketClientConnection::LoopThreadDelegate::LoopThreadDelegate(
+ MessageQueue<Message, AsyncQueue>* message_queue,
+ WebsocketClientConnection* handler)
+ : message_queue_(*message_queue), handler_(*handler), shutdown_(false) {}
+
+void WebsocketClientConnection::LoopThreadDelegate::threadMain() {
+ while (!message_queue_.IsShuttingDown() && !shutdown_) {
+ DrainQueue();
+ message_queue_.wait();
+ }
+ DrainQueue();
+}
+
+void WebsocketClientConnection::LoopThreadDelegate::exitThreadMain() {
+ shutdown_ = true;
+ if (!message_queue_.IsShuttingDown()) {
+ message_queue_.Shutdown();
+ }
+}
+
+void WebsocketClientConnection::LoopThreadDelegate::DrainQueue() {
+ while (!message_queue_.empty()) {
+ Message message_ptr;
+ message_queue_.pop(message_ptr);
+ if (!shutdown_) {
+ boost::system::error_code ec;
+ handler_.ws_.write(
+ 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,
+ DataSendError());
+ }
+ }
+ }
+}
+
+void WebsocketClientConnection::LoopThreadDelegate::SetShutdown() {
+ shutdown_ = true;
+ if (!message_queue_.IsShuttingDown()) {
+ message_queue_.Shutdown();
+ }
+}
+
+} // namespace transport_adapter
+} // namespace transport_manager \ No newline at end of file
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..38b9bd3998 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
@@ -60,7 +60,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(
@@ -743,6 +745,24 @@ DeviceSptr TransportAdapterImpl::FindDevice(const DeviceUID& device_id) const {
return ret;
}
+void TransportAdapterImpl::ConnectPending(const DeviceUID& device_id,
+ const ApplicationHandle& app_handle) {
+ connections_lock_.AcquireForReading();
+ 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();
+
+ 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_,
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 544cdde999..73750fe2f3 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
@@ -116,6 +116,27 @@ void TransportAdapterListenerImpl::OnFindNewApplicationsRequest(
LOG4CXX_TRACE(logger_, "exit");
}
+void TransportAdapterListenerImpl::OnConnectPending(
+ const TransportAdapter* adapter,
+ const DeviceUID& device,
+ const ApplicationHandle& application_id) {
+ LOG4CXX_TRACE(logger_,
+ "enter adapter*: " << adapter << ", device: " << &device
+ << ", application_id: " << &application_id);
+ const TransportAdapterEvent event(EventTypeEnum::ON_CONNECT_PENDING,
+ transport_adapter_,
+ device,
+ application_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::OnConnectDone(
const TransportAdapter* adapter,
const DeviceUID& device,
diff --git a/src/components/transport_manager/src/transport_manager_default.cc b/src/components/transport_manager/src/transport_manager_default.cc
index 196ad09af4..bf692de24c 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(CLOUD_APP_WEBSOCKET_TRANSPORT_SUPPORT)
+#include "transport_manager/cloud/cloud_websocket_transport_adapter.h"
+#endif
+
#if defined(BUILD_TESTS)
#include "transport_manager/iap2_emulation/iap2_transport_adapter.h"
#endif // BUILD_TEST
@@ -101,6 +105,20 @@ int TransportManagerDefault::Init(resumption::LastState& last_state) {
ta_usb = NULL;
#endif // USB_SUPPORT
+#if defined CLOUD_APP_WEBSOCKET_TRANSPORT_SUPPORT
+ transport_adapter::TransportAdapterImpl* ta_cloud =
+ new transport_adapter::CloudWebsocketTransportAdapter(
+ last_state, get_settings()); // Todo add retry connection logic from
+ // ini to initializer.
+#ifdef TELEMETRY_MONITOR
+ if (metric_observer_) {
+ ta_cloud->SetTelemetryObserver(metric_observer_);
+ }
+#endif // TELEMETRY_MONITOR
+ AddTransportAdapter(ta_cloud);
+ ta_cloud = NULL;
+#endif
+
#if defined BUILD_TESTS
const uint16_t iap2_bt_emu_port = 23456;
transport_adapter::IAP2BluetoothEmulationTransportAdapter*
diff --git a/src/components/transport_manager/src/transport_manager_impl.cc b/src/components/transport_manager/src/transport_manager_impl.cc
index 2b0296debb..300ed27718 100644
--- a/src/components/transport_manager/src/transport_manager_impl.cc
+++ b/src/components/transport_manager/src/transport_manager_impl.cc
@@ -129,6 +129,26 @@ void TransportManagerImpl::ReconnectionTimeout() {
device_to_reconnect_);
}
+void TransportManagerImpl::AddCloudDevice(
+ const std::string& endpoint, const std::string& cloud_transport_type) {
+ // todo put conversion into own function
+ transport_adapter::DeviceType type = transport_adapter::DeviceType::UNKNOWN;
+ if (cloud_transport_type == "WS") {
+ type = transport_adapter::DeviceType::CLOUD_WEBSOCKET;
+ } else {
+ return;
+ }
+
+ std::vector<TransportAdapter*>::iterator ta = transport_adapters_.begin();
+ for (; ta != transport_adapters_.end(); ++ta) {
+ if ((*ta)->GetDeviceType() == type) {
+ (*ta)->CreateDevice(endpoint);
+ }
+ }
+
+ return;
+}
+
int TransportManagerImpl::ConnectDevice(const DeviceHandle device_handle) {
LOG4CXX_TRACE(logger_, "enter. DeviceHandle: " << &device_handle);
if (!this->is_initialized_) {
@@ -954,7 +974,7 @@ void TransportManagerImpl::Handle(TransportAdapterEvent event) {
LOG4CXX_DEBUG(logger_, "event_type = ON_FIND_NEW_APPLICATIONS_REQUEST");
break;
}
- case EventTypeEnum::ON_CONNECT_DONE: {
+ case EventTypeEnum::ON_CONNECT_PENDING: {
const DeviceHandle device_handle = converter_.UidToHandle(
event.device_uid, event.transport_adapter->GetConnectionType());
AddConnection(ConnectionInternal(this,
@@ -964,12 +984,55 @@ void TransportManagerImpl::Handle(TransportAdapterEvent event) {
event.application_id,
device_handle));
RaiseEvent(
- &TransportManagerListener::OnConnectionEstablished,
+ &TransportManagerListener::OnConnectionPending,
DeviceInfo(device_handle,
event.device_uid,
event.transport_adapter->DeviceName(event.device_uid),
event.transport_adapter->GetConnectionType()),
connection_id_counter_);
+ LOG4CXX_DEBUG(logger_, "event_type = ON_CONNECT_PENDING");
+ break;
+ }
+ case EventTypeEnum::ON_CONNECT_DONE: {
+ const DeviceHandle device_handle = converter_.UidToHandle(
+ event.device_uid, event.transport_adapter->GetConnectionType());
+
+ 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::OnConnectionEstablished,
+ DeviceInfo(device_handle,
+ event.device_uid,
+ event.transport_adapter->DeviceName(event.device_uid),
+ event.transport_adapter->GetConnectionType()),
+ connection_id);
LOG4CXX_DEBUG(logger_, "event_type = ON_CONNECT_DONE");
break;
}
diff --git a/src/components/transport_manager/test/CMakeLists.txt b/src/components/transport_manager/test/CMakeLists.txt
index 240784436b..5288d8c697 100644
--- a/src/components/transport_manager/test/CMakeLists.txt
+++ b/src/components/transport_manager/test/CMakeLists.txt
@@ -75,6 +75,11 @@ if (BUILD_BT_SUPPORT)
endif()
endif()
+if(BUILD_CLOUD_APP_SUPPORT)
+ GET_PROPERTY(BOOST_LIBS_DIRECTORY GLOBAL PROPERTY GLOBAL_BOOST_LIBS)
+ list(APPEND LIBRARIES boost_system boost_regex crypto ssl -L${BOOST_LIBS_DIRECTORY})
+endif()
+
create_test("transport_manager_test" "${SOURCES}" "${LIBRARIES}")
file(COPY smartDeviceLink_test.ini DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
diff --git a/src/components/transport_manager/test/include/transport_manager/mock_transport_manager_listener.h b/src/components/transport_manager/test/include/transport_manager/mock_transport_manager_listener.h
index 58e143342a..4eaf34d041 100644
--- a/src/components/transport_manager/test/include/transport_manager/mock_transport_manager_listener.h
+++ b/src/components/transport_manager/test/include/transport_manager/mock_transport_manager_listener.h
@@ -56,6 +56,9 @@ class MockTransportManagerListener : public TransportManagerListener {
MOCK_METHOD1(OnDeviceRemoved, void(const DeviceInfo& device_info));
MOCK_METHOD0(OnScanDevicesFinished, void());
MOCK_METHOD1(OnScanDevicesFailed, void(const SearchDeviceError& error));
+ MOCK_METHOD2(OnConnectionPending,
+ void(const DeviceInfo& device_info,
+ const ConnectionUID connection_id));
MOCK_METHOD2(OnConnectionEstablished,
void(const DeviceInfo& device_info,
const ConnectionUID connection_id));
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 dce23189c8..81e133ec2b 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
@@ -59,6 +59,10 @@ class MockTransportAdapterListener : public TransportAdapterListener {
const SearchDeviceError& error));
MOCK_METHOD1(OnFindNewApplicationsRequest,
void(const TransportAdapter* adapter));
+ MOCK_METHOD3(OnConnectPending,
+ void(const TransportAdapter* adapter,
+ const DeviceUID& device_handle,
+ const ApplicationHandle& app_id));
MOCK_METHOD1(OnDeviceListUpdated,
void(const TransportAdapter* transport_adapter));
MOCK_METHOD3(OnConnectDone,
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 5205d6ae3c..f44f8785aa 100644
--- a/src/components/transport_manager/test/tcp_client_listener_test.cc
+++ b/src/components/transport_manager/test/tcp_client_listener_test.cc
@@ -73,6 +73,9 @@ class MockTransportAdapterController : public TransportAdapterController {
void(ConnectionSPtr connection,
const DeviceUID& device_handle,
const ApplicationHandle& app_handle));
+ MOCK_METHOD2(ConnectPending,
+ void(const DeviceUID& device_handle,
+ const ApplicationHandle& app_handle));
MOCK_METHOD2(ConnectDone,
void(const DeviceUID& device_handle,
const ApplicationHandle& app_handle));