diff options
author | JackLivio <jack@livio.io> | 2018-11-08 09:42:04 -0500 |
---|---|---|
committer | JackLivio <jack@livio.io> | 2018-11-08 09:42:04 -0500 |
commit | 2e262bb5c5f0d4a8462579024dfe7ef7e64487a9 (patch) | |
tree | b03846f546a34c1c82ea132d307d459e438c679f /src/components/transport_manager | |
parent | 3e9929e6095acd4abd2be24714fb03f9246e7036 (diff) | |
download | sdl_core-2e262bb5c5f0d4a8462579024dfe7ef7e64487a9.tar.gz |
Initial Cloud Transport Component
Diffstat (limited to 'src/components/transport_manager')
9 files changed, 949 insertions, 0 deletions
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* |