diff options
17 files changed, 1041 insertions, 1 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/appMain/smartDeviceLink.ini b/src/appMain/smartDeviceLink.ini index b0513c076f..ac3e1c983a 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 = +[Cloud App Connections] +; 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/config_profile/include/config_profile/profile.h b/src/components/config_profile/include/config_profile/profile.h index 57e925cd43..da087086c2 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 + */ + uint16_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_; + uint16_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..5b4c2e5f93 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 = "Cloud App Connections"; 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_; } +uint16_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/src/connection_handler_impl.cc b/src/components/connection_handler/src/connection_handler_impl.cc index 399dbf90d7..290b1a650e 100644 --- a/src/components/connection_handler/src/connection_handler_impl.cc +++ b/src/components/connection_handler/src/connection_handler_impl.cc @@ -142,6 +142,8 @@ 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(), @@ -248,7 +250,7 @@ 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!"); diff --git a/src/components/hmi_message_handler/src/websocket_session.cc b/src/components/hmi_message_handler/src/websocket_session.cc index a148f48661..041a89ef82 100644 --- a/src/components/hmi_message_handler/src/websocket_session.cc +++ b/src/components/hmi_message_handler/src/websocket_session.cc @@ -71,6 +71,7 @@ bool WebsocketSession::IsShuttingDown() { } void WebsocketSession::Recv(boost::system::error_code ec) { + printf("!!!server recv connection accepted\n"); if (shutdown_) { return; } 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..6af29aa7c2 100644 --- a/src/components/include/transport_manager/transport_adapter/transport_adapter.h +++ b/src/components/include/transport_manager/transport_adapter/transport_adapter.h @@ -64,12 +64,28 @@ 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 UNKNOWN }; +enum HybridAppPreference { // todo find correct place for this enum defintion. + MOBILE, + CLOUD, + BOTH +}; + +struct CloudAppProperties { + std::string endpoint; + std::string certificate; + bool enabled; + std::string auth_token; + DeviceType cloud_transport_type; + HybridAppPreference hybrid_app_preference; +}; + typedef std::map<DeviceType, std::string> DeviceTypes; /** @@ -89,6 +105,11 @@ typedef std::list<TransportAdapterListener*> TransportAdapterListenerList; typedef std::map<std::string, std::string> TransportConfig; /** + * @brief Type definition of container indexed by app id that contains connection information for all cloud apps. + */ +typedef std::map<std::string, CloudAppProperties> CloudAppTransportConfig; + +/** * @brief TransportConfig keys */ extern const char* tc_enabled; diff --git a/src/components/include/transport_manager/transport_manager_settings.h b/src/components/include/transport_manager/transport_manager_settings.h index 3912bbe747..d59038e5c6 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 uint16_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/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..5792ba06a1 --- /dev/null +++ b/src/components/transport_manager/include/transport_manager/cloud/cloud_device.h @@ -0,0 +1,64 @@ +/* + * 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); + + protected: + virtual bool IsSameAs(const Device* other_device) const; + + virtual ApplicationList GetApplicationList() const; + + private: + //todo add private varaibles, maybe ip port or other connection information? +}; + +} // 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..ad31bd33b3 --- /dev/null +++ b/src/components/transport_manager/include/transport_manager/cloud/cloud_websocket_transport_adapter.h @@ -0,0 +1,105 @@ +/* + * \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(); + + /** + * @brief Notification that transport's configuration is updated + * + * @param new_config The new configuration of the transport + */ + void CloudTransportConfigUpdated(const CloudAppTransportConfig& new_config); + + /** + * @brief Returns the transport's configuration information + */ + CloudAppTransportConfig GetCloudTransportConfiguration() const; + + 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(); + + private: + /** + * @brief Keeps transport specific configuration + * + * Cloud websocket transport uses following information: + * - "enabled": whether the transport is currently enabled or not. Value can + * be "true" or "false". + */ + CloudAppTransportConfig transport_config_; +}; + +} // 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..38eb663b1c --- /dev/null +++ b/src/components/transport_manager/include/transport_manager/cloud/websocket_client_connection.h @@ -0,0 +1,180 @@ +/* + * \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/src/cloud/cloud_device.cc b/src/components/transport_manager/src/cloud/cloud_device.cc new file mode 100644 index 0000000000..ab7f8db69a --- /dev/null +++ b/src/components/transport_manager/src/cloud/cloud_device.cc @@ -0,0 +1,62 @@ +/* + * + * 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+port)) {} + + +bool CloudDevice::IsSameAs(const Device* other) const { + LOG4CXX_TRACE(logger_, "enter. device: " << other); + bool result = false; + return result; +} + +//todo implement getApplicationList +//to be populated by policies +ApplicationList CloudDevice::GetApplicationList() const { + return ApplicationList{100}; +} + + +} // 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..d566dd9bf8 --- /dev/null +++ b/src/components/transport_manager/src/cloud/cloud_websocket_connection_factory.cc @@ -0,0 +1,99 @@ +/* + * \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() { + DeviceUID device_id = "Cloud"; + ApplicationHandle app_handle = 100; + printf("Calling create connection\n"); + + std::string host("192.168.1.69"); + std::string port("8080"); + + //todo move this device logic to the correct place. + auto cloud_device = std::make_shared<CloudDevice>( + host,port,device_id); + DeviceVector devices{cloud_device}; + + controller_->SearchDeviceDone(devices); + + + const TransportAdapter::Error err = + this->CreateConnection(std::string(device_id+host+port), app_handle); + LOG4CXX_DEBUG(logger_, err); + return TransportAdapter::OK; +} + +TransportAdapter::Error CloudWebsocketConnectionFactory::CreateConnection( + const DeviceUID& device_uid, const ApplicationHandle& app_handle) { + LOG4CXX_AUTO_TRACE(logger_); + printf("Create connection()\n"); + 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..29ea6e5b27 --- /dev/null +++ b/src/components/transport_manager/src/cloud/cloud_websocket_transport_adapter.cc @@ -0,0 +1,73 @@ +/* + * 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" + +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) { + + /*DeviceUID device_id = "Cloud"; + ApplicationHandle app_handle = 100; + printf("Calling create connection\n"); + const TransportAdapter::Error err = + server_connection_factory_->CreateConnection(device_id, app_handle); + LOG4CXX_DEBUG(logger_, err);*/ +} + +CloudWebsocketTransportAdapter::~CloudWebsocketTransportAdapter() {} + +void CloudWebsocketTransportAdapter::CloudTransportConfigUpdated(const CloudAppTransportConfig& new_config) {} + +CloudAppTransportConfig CloudWebsocketTransportAdapter::GetCloudTransportConfiguration() const { return transport_config_; } + +DeviceType CloudWebsocketTransportAdapter::GetDeviceType() const { + return CLOUD_WEBSOCKET; +} + +void CloudWebsocketTransportAdapter::Store() const {} // todo decide if this is needed + +bool CloudWebsocketTransportAdapter::Restore() { // todo decide if resumption is needed + return true; +} + + + + + +} +}
\ 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..96641f5cb2 --- /dev/null +++ b/src/components/transport_manager/src/cloud/websocket_client_connection.cc @@ -0,0 +1,252 @@ +/* + * + * Copyright (c) 2017, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "transport_manager/cloud/websocket_client_connection.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_); + printf("Calling websocket start\n"); + auto const host = "192.168.1.69"; + auto const port = "8080"; + boost::system::error_code ec; + auto const results = resolver_.resolve(host, port, ec); + if (ec) { + std::string str_err = "ErrorMessage1: " + ec.message(); + printf("%s\n", str_err.c_str()); + Shutdown(); + return TransportAdapter::FAIL; + } + boost::asio::connect(ws_.next_layer(), results.begin(), results.end(), ec); + if (ec) { + std::string str_err = "ErrorMessage2: " + ec.message(); + printf("%s\n", str_err.c_str()); + Shutdown(); + return TransportAdapter::FAIL; + } + ws_.handshake(host, "/", ec); + if (ec) { + std::string str_err = "ErrorMessage3: " + ec.message(); + printf("%s\n", str_err.c_str()); + 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(); printf("io_service_thread_ END!!!\n"); + }); + + // Start async write thread + + printf("End of websockets\n"); + + return TransportAdapter::OK; +} + +void WebsocketClientConnection::Recv(boost::system::error_code ec) { + printf("Recv\n"); + if (shutdown_) { + printf("shutdown_\n"); + return; + } + + if (ec) { + std::string str_err = "ErrorMessage: " + ec.message(); + printf("%s\n", str_err.c_str()); + LOG4CXX_ERROR(logger_, str_err); + //shutdown_ = true; + //ioc_.stop(); + //thread_delegate_->SetShutdown(); + //controller_->deleteController(this); + Shutdown(); + return; + } + printf("calling async read\n"); + + 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) { + printf("OnRead\n"); + boost::ignore_unused(bytes_transferred); + if (ec) { + std::string str_err = "ErrorMessage: " + ec.message(); + printf("%s\n", str_err.c_str()); + LOG4CXX_ERROR(logger_, str_err); + Shutdown(); + controller_->ConnectionAborted( + device_uid_, app_handle_, CommunicationError()); + + printf("return error\n"); + return; + } + + std::string data_str = boost::beast::buffers_to_string(buffer_.data()); + LOG4CXX_DEBUG(logger_, "Cloud Transport Received: " << data_str); + printf("%s\n", data_str.c_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_); + printf("Send DATA!!!\n"); + sync_primitives::AutoLock auto_lock(frames_to_send_mutex_); + message_queue_.push(message); + printf("Data pushed to queue!!!\n"); + 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(); + printf("Joined Thread Delegate!!!\n"); + delete thread_delegate_; + } + if (buffer_.size()) { + buffer_.consume(buffer_.size()); + } + printf("End of shutdown!!!\n"); +} + +WebsocketClientConnection::LoopThreadDelegate::LoopThreadDelegate( + MessageQueue<Message, AsyncQueue>* message_queue, WebsocketClientConnection* handler) + : message_queue_(*message_queue), handler_(*handler), shutdown_(false) {} + +void WebsocketClientConnection::LoopThreadDelegate::threadMain() { + printf("Starting write thread\n"); + 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_) { + printf("Calling Write!!!\n"); + 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_manager_default.cc b/src/components/transport_manager/src/transport_manager_default.cc index 196ad09af4..f78c31c0d5 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,18 @@ int TransportManagerDefault::Init(resumption::LastState& last_state) { ta_usb = NULL; #endif // USB_SUPPORT +#if defined CLOUD_APP_WEBSOCKET_TRANSPORT_SUPPORT + printf("Creating cloud transport\n"); + 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* |