diff --git a/.travis.yml b/.travis.yml index 34ed0e7d1..db18b6f98 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,8 +14,7 @@ compiler: # it will not be necessary once travis worker is based on ubuntu > 12.04. # Install SWIG for bindings generation # Install valgrind for memcheck tests -# Adding kubuntu-backports ppa for for cmake 2.8.12. -# it is needed in case of multiple python version on host +# Adding george-edison55-precise-backports ppa for for cmake 3.x. # Install python3-dev for the client simulator addons: apt: @@ -23,7 +22,7 @@ addons: # https://github.com/travis-ci/apt-source-whitelist/blob/master/ubuntu.json sources: - ubuntu-toolchain-r-test - - kubuntu-backports + - george-edison55-precise-backports - llvm-toolchain-precise # Travis white list of dpkg packages # https://github.com/travis-ci/apt-package-whitelist/blob/master/ubuntu-precise @@ -31,9 +30,9 @@ addons: - swig - valgrind - g++-4.8 + - cmake-data - cmake - python3-dev - - libasio-dev - clang-format-3.8 install: @@ -80,6 +79,13 @@ script: cmake -DCMAKE_INSTALL_PREFIX=../install . && make && make install ) + # Keep this last + - ( mkdir build_less_features && cd build_less_features && + rm -rf $PREFIX/asio-1.10.6 && + cmake -DCMAKE_PREFIX_PATH=$PREFIX -DCMAKE_BUILD_TYPE=Debug + -DNETWORKING=OFF -DPYTHON_BINDINGS=OFF -DC_BINDINGS=OFF .. && + make -j && + CTEST_OUTPUT_ON_FAILURE=1 make test ) after_success: # Push coverage info on codecov.io. diff --git a/CMakeLists.txt b/CMakeLists.txt index e8b5edaaa..8bf794113 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2014-2015, Intel Corporation +# Copyright (c) 2014-2016, Intel Corporation # All rights reserved. # # Redistribution and use in source and binary forms, with or without modification, @@ -26,10 +26,12 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# working on 2.8.12 - broken on older versions. +# Known to work with CMake 3.2.2, might work with older 3.x versions, will not +# work with versions prior to 3.0.0. # Visual Studio 14 needs 3.3.0; see https://cmake.org/Bug/print_bug_page.php?bug_id=15552 -cmake_minimum_required(VERSION 2.8.12) -if(CMAKE_GENERATOR STRGREATER "Visual Studio 14 2015") +cmake_minimum_required(VERSION 3.2.2) +if((CMAKE_GENERATOR MATCHES "Visual Studio .*") + AND (CMAKE_GENERATOR STRGREATER "Visual Studio 14 2015")) cmake_minimum_required(VERSION 3.3.0) endif() @@ -47,6 +49,7 @@ option(REQUIREMENTS "Generate the html version of the 'requirements' documentati option(PYTHON_BINDINGS "Python library to use the Parameter Framework from python" ON) option(C_BINDINGS "Library to use the Parameter Framework using a C API" ON) option(FATAL_WARNINGS "Turn warnings into errors (-Werror flag)" ON) +option(NETWORKING "Set to OFF in order to stub networking code" ON) include(SetVersion.cmake) @@ -102,6 +105,7 @@ endif() add_subdirectory(xmlserializer) add_subdirectory(parameter) add_subdirectory(utility) +add_subdirectory(asio) add_subdirectory(remote-processor) add_subdirectory(remote-process) diff --git a/README.md b/README.md index f5023f882..59ae1e69d 100644 --- a/README.md +++ b/README.md @@ -73,20 +73,26 @@ sections: In order to compile you'll need, at the very least: -- CMake (v2.8.12 or later) (v3.3.0 or later on Windows); +- CMake (v3.2.2 or later) (v3.3.0 or later on Windows); - A C/C++ compiler supporting C++11; - libxml2 headers and libraries (Provided by the `libxml2-dev` on debian-based distributions); + +If you want to use the remote command interface (`NETWORKING=ON` by default), +you'll also need: + - Standalone ASIO (1.10.6 or later) (Provided by `libasio-dev` on debian-based distributions) ASIO is C++ header-only ASynchronous-IO library. -If you want to compile the *Python bindings*, you'll also need: +If you want to compile the *Python bindings* (`PYTHON_BINDINGS=ON` by default), +you'll also need: - SWIG 2.0 (A binding generator); - Python2.7 development environment (Provided by `python2.7-dev` on debian-based distributions) -If you want to *compile and run the tests*, you'll also need: +If you want to *compile and run the tests* (`BUILD_TESTING=ON` by default), +you'll also need: - Catch (Provided by `catch` on debian-based distributions). Catch is a single-header test framework - as such you may also download it directly @@ -94,8 +100,9 @@ single-header test framework - as such you may also download it directly - Python2.7 (Provided by `python2.7` on debian-based distribution - it is preinstalled on most distributions). -If you want to *build the code documentation*, you'll need `doxygen` and -`graphviz`. This doc is already available to you - see the wiki. +If you want to *build the code documentation* (`DOXYGEN=OFF` by default), you'll +need `doxygen` and `graphviz`. This doc is already available to you - see the +wiki. **To list all available configuration options, try** `cmake -L` (you may also filter-out lines starting with `CMAKE_`). diff --git a/asio/CMakeLists.txt b/asio/CMakeLists.txt new file mode 100644 index 000000000..9c0ef115b --- /dev/null +++ b/asio/CMakeLists.txt @@ -0,0 +1,57 @@ +# Copyright (c) 2016, Intel Corporation +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# 2. 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. +# +# 3. Neither the name of the copyright holder 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. + +add_library(asio INTERFACE) + +if (NETWORKING) + # Find ASIO (the standalone version, not Boost) If asio isn't installed in + # a standard directory, add the correct directory to CMAKE_PREFIX_PATH (see + # the main README for more information). + find_path(ASIO_DIR NAMES asio.hpp) + # Hide this variable from CMake GUIs and `cmake -L` + set_property(CACHE ASIO_DIR PROPERTY ADVANCED TRUE) + if (NOT ASIO_DIR) + message(SEND_ERROR + " ASIO header (asio.hpp) could not be found. + ASIO is used for networking. On Linux, you should install it using your + package manager. On Windows, please refer to the main README.") + endif() + + # Ubuntu 14.04 packages asio 1.10.1 and clang 3.4.1. + # In this environment, asio stand alone (set ASIO_STANDALONE) + # does not correcly detect that the stl has CHRONO support (c++11). + # Force the use of std::chrono by setting ASIO_HAS_STD_CHRONO + target_include_directories(asio SYSTEM INTERFACE "${ASIO_DIR}") + target_link_libraries(asio INTERFACE "${CMAKE_THREAD_LIBS_INIT}") + target_compile_definitions(asio + INTERFACE ASIO_STANDALONE + INTERFACE ASIO_HAS_STD_CHRONO) +else() + # Stubbed version + target_include_directories(asio INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/stub") +endif() diff --git a/asio/stub/asio.hpp b/asio/stub/asio.hpp new file mode 100644 index 000000000..84a0ea4ec --- /dev/null +++ b/asio/stub/asio.hpp @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2016, Intel Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ +#pragma once + +/** @file + * + * Stubs ASIO interfaces called by libremote-processor. This is used when + * the user asks for networking support to be compiled out. + */ + +#include + +namespace asio +{ +struct dummy_base +{ + template + dummy_base(Args &&...) + { + } + void set_option(const dummy_base &) const {}; +}; +inline bool write(const dummy_base &, const dummy_base &, const dummy_base &) +{ + return true; +} +inline bool read(const dummy_base &, const dummy_base &, const dummy_base &) +{ + return true; +} +using buffer = dummy_base; +struct io_service : dummy_base +{ + template + io_service(Args &&...) + { + throw std::runtime_error("Stub constructor called. Did you forget to set the " + "'TuningAllowed' attribute to 'false' in the Parameter " + "Framework's toplevel configuration file?"); + } + + void run(const dummy_base &) const {}; + void stop() const {}; +}; +struct socket_base : dummy_base +{ + using dummy_base::dummy_base; + + using linger = dummy_base; + using enable_connection_aborted = dummy_base; + void close() const {}; +}; + +bool write(const dummy_base &, const dummy_base &, const dummy_base &); +bool read(const dummy_base &, const dummy_base &, const dummy_base &); + +struct error_code : dummy_base, std::error_code +{ +}; +namespace error +{ +static const error_code eof{}; +} + +namespace ip +{ +namespace tcp +{ +using v6 = dummy_base; +using no_delay = dummy_base; +using socket = socket_base; +struct endpoint : dummy_base +{ + using dummy_base::dummy_base; + + dummy_base protocol() const { return {}; }; +}; +struct acceptor : dummy_base +{ + using dummy_base::dummy_base; + + using reuse_address = dummy_base; + void open(const dummy_base &) const {}; + void bind(const dummy_base &) const {}; + void listen() const {}; + void async_accept(const dummy_base &, const dummy_base &) const {}; +}; +} +} +} diff --git a/parameter/ParameterMgr.cpp b/parameter/ParameterMgr.cpp index dd6724527..f45056325 100644 --- a/parameter/ParameterMgr.cpp +++ b/parameter/ParameterMgr.cpp @@ -67,7 +67,7 @@ #include "BitParameterType.h" #include "StringParameterType.h" #include "EnumParameterType.h" -#include "BackgroundRemoteProcessorServerBuilder.h" +#include "BackgroundRemoteProcessorServer.h" #include "ElementLocator.h" #include "CompoundRule.h" #include "SelectionCriterionRule.h" @@ -2855,8 +2855,13 @@ bool CParameterMgr::handleRemoteProcessingInterface(string &strError) auto port = getConstFrameworkConfiguration()->getServerPort(); - // The ownership of remoteComandHandler is given to Bg remote processor server. - _pRemoteProcessorServer = new BackgroundRemoteProcessorServer(port, createCommandHandler()); + try { + // The ownership of remoteComandHandler is given to Bg remote processor server. + _pRemoteProcessorServer = new BackgroundRemoteProcessorServer(port, createCommandHandler()); + } catch (std::runtime_error &e) { + strError = string("ParameterMgr: Unable to create Remote Processor Server: ") + e.what(); + return false; + } if (_pRemoteProcessorServer == NULL) { strError = "ParameterMgr: Unable to create Remote Processor Server"; diff --git a/remote-process/CMakeLists.txt b/remote-process/CMakeLists.txt index dbfb2ebc7..e27a101e8 100644 --- a/remote-process/CMakeLists.txt +++ b/remote-process/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2014, Intel Corporation +# Copyright (c) 2014-2016, Intel Corporation # All rights reserved. # # Redistribution and use in source and binary forms, with or without modification, @@ -26,17 +26,14 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -add_executable(remote-process main.cpp) +if(NETWORKING) + add_executable(remote-process main.cpp) -set(CMAKE_THREAD_PREFER_PTHREAD 1) -find_package(Threads REQUIRED) + set(CMAKE_THREAD_PREFER_PTHREAD 1) + find_package(Threads REQUIRED) -target_link_libraries(remote-process - PRIVATE remote-processor pfw_utility - # Remote-process does not use thread, - # nevertheless it uses asio resolver wich may use a thread (for async resolve). - # As a result remote-process must link with a thread library although not - # using the corresponding symbols. - PRIVATE "${CMAKE_THREAD_LIBS_INIT}") + target_link_libraries(remote-process + PRIVATE remote-processor pfw_utility asio ${CMAKE_THREAD_LIBS_INIT}) -install(TARGETS remote-process RUNTIME DESTINATION bin) + install(TARGETS remote-process RUNTIME DESTINATION bin) +endif() diff --git a/remote-process/main.cpp b/remote-process/main.cpp index ef202e324..3ebaa86b3 100644 --- a/remote-process/main.cpp +++ b/remote-process/main.cpp @@ -36,6 +36,7 @@ #include #include "RequestMessage.h" #include "AnswerMessage.h" +#include "Socket.h" using namespace std; @@ -43,7 +44,7 @@ bool sendAndDisplayCommand(asio::ip::tcp::socket &socket, CRequestMessage &reque { string strError; - if (requestMessage.serialize(socket, true, strError) != CRequestMessage::success) { + if (requestMessage.serialize(Socket(socket), true, strError) != CRequestMessage::success) { cerr << "Unable to send command to target: " << strError << endl; return false; @@ -51,7 +52,7 @@ bool sendAndDisplayCommand(asio::ip::tcp::socket &socket, CRequestMessage &reque ///// Get answer CAnswerMessage answerMessage; - if (answerMessage.serialize(socket, false, strError) != CRequestMessage::success) { + if (answerMessage.serialize(Socket(socket), false, strError) != CRequestMessage::success) { cerr << "Unable to received answer from target: " << strError << endl; return false; diff --git a/remote-processor/BackgroundRemoteProcessorServer.cpp b/remote-processor/BackgroundRemoteProcessorServer.cpp new file mode 100644 index 000000000..08207864c --- /dev/null +++ b/remote-processor/BackgroundRemoteProcessorServer.cpp @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2016, Intel Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. 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. + * + * 3. Neither the name of the copyright holder 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 "BackgroundRemoteProcessorServer.h" +#include "RemoteProcessorServer.h" + +BackgroundRemoteProcessorServer::BackgroundRemoteProcessorServer( + uint16_t uiPort, std::unique_ptr &&commandHandler) + : _server(new CRemoteProcessorServer(uiPort)), mCommandHandler(std::move(commandHandler)) +{ +} + +bool BackgroundRemoteProcessorServer::start(std::string &error) +{ + if (!_server->start(error)) { + return false; + } + try { + mServerSuccess = std::async(std::launch::async, &CRemoteProcessorServer::process, + _server.get(), std::ref(*mCommandHandler)); + } catch (std::exception &e) { + error = "Could not create a remote processor thread: " + std::string(e.what()); + return false; + } + + return true; +} + +bool BackgroundRemoteProcessorServer::stop() +{ + _server->stop(); + return mServerSuccess.get(); +} + +BackgroundRemoteProcessorServer::~BackgroundRemoteProcessorServer() +{ + stop(); +} diff --git a/remote-processor/BackgroundRemoteProcessorServerBuilder.h b/remote-processor/BackgroundRemoteProcessorServer.h similarity index 66% rename from remote-processor/BackgroundRemoteProcessorServerBuilder.h rename to remote-processor/BackgroundRemoteProcessorServer.h index cebbad0bf..1c17fca82 100644 --- a/remote-processor/BackgroundRemoteProcessorServerBuilder.h +++ b/remote-processor/BackgroundRemoteProcessorServer.h @@ -27,45 +27,30 @@ * (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 "RemoteProcessorServer.h" +#include "RemoteProcessorServerInterface.h" +#include "RemoteCommandHandler.h" #include #include -class BackgroundRemoteProcessorServer final : public IRemoteProcessorServerInterface +#include "remote_processor_export.h" + +class CRemoteProcessorServer; + +class REMOTE_PROCESSOR_EXPORT BackgroundRemoteProcessorServer final + : public IRemoteProcessorServerInterface { public: BackgroundRemoteProcessorServer(uint16_t uiPort, - std::unique_ptr &&commandHandler) - : _server(uiPort), mCommandHandler(std::move(commandHandler)) - { - } - - ~BackgroundRemoteProcessorServer() { stop(); } + std::unique_ptr &&commandHandler); - bool start(std::string &error) override - { - if (!_server.start(error)) { - return false; - } - try { - mServerSuccess = std::async(std::launch::async, &CRemoteProcessorServer::process, - &_server, std::ref(*mCommandHandler)); - } catch (std::exception &e) { - error = "Could not create a remote processor thread: " + std::string(e.what()); - return false; - } + ~BackgroundRemoteProcessorServer(); - return true; - } + bool start(std::string &error) override; - bool stop() override - { - _server.stop(); - return mServerSuccess.get(); - } + bool stop() override; private: - CRemoteProcessorServer _server; + std::unique_ptr _server; std::unique_ptr mCommandHandler; std::future mServerSuccess; }; diff --git a/remote-processor/CMakeLists.txt b/remote-processor/CMakeLists.txt index 774927973..ee21f55b6 100644 --- a/remote-processor/CMakeLists.txt +++ b/remote-processor/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2014-2015, Intel Corporation +# Copyright (c) 2014-2016, Intel Corporation # All rights reserved. # # Redistribution and use in source and binary forms, with or without modification, @@ -30,7 +30,8 @@ add_library(remote-processor SHARED Message.cpp RequestMessage.cpp AnswerMessage.cpp - RemoteProcessorServer.cpp) + RemoteProcessorServer.cpp + BackgroundRemoteProcessorServer.cpp) include(GenerateExportHeader) generate_export_header(remote-processor @@ -39,28 +40,12 @@ generate_export_header(remote-processor set(CMAKE_THREAD_PREFER_PTHREAD 1) find_package(Threads REQUIRED) -# Find ASIO (the standalone version, not Boost) and declare it as a dependency -# for remote-processor's users too. (FIXME: this should not be the case) -# If asio isn't installed in a standard directory, add the correct directory to -# CMAKE_PREFIX_PATH (see the main README for more information). -find_path(ASIO_DIR NAMES asio.hpp) -# Hide this variable from CMake GUIs and `cmake -L` -set_property(CACHE ASIO_DIR PROPERTY ADVANCED TRUE) -# FIXME: asio header should not leak to remote-processor users -target_include_directories(remote-processor SYSTEM PUBLIC "${ASIO_DIR}") - -# Ubuntu 14.04 packages asio 1.10.1 and clang 3.4.1. -# In this environment, asio stand alone (set ASIO_STANDALONE) -# does not correcly detect that the stl has CHRONO support (c++11). -# Force the use of std::chrono by setting ASIO_HAS_STD_CHRONO -target_compile_definitions(remote-processor PUBLIC ASIO_STANDALONE ASIO_HAS_STD_CHRONO) - target_include_directories(remote-processor # Symbol export macro header PUBLIC "${CMAKE_CURRENT_BINARY_DIR}" # TODO: separate remote-processor's includes in half (public/private) PUBLIC .) -target_link_libraries(remote-processor PRIVATE pfw_utility ${CMAKE_THREAD_LIBS_INIT}) +target_link_libraries(remote-processor PRIVATE pfw_utility asio ${CMAKE_THREAD_LIBS_INIT}) install(TARGETS remote-processor LIBRARY DESTINATION lib RUNTIME DESTINATION bin) diff --git a/remote-processor/Message.cpp b/remote-processor/Message.cpp index af7556120..66154ec8b 100644 --- a/remote-processor/Message.cpp +++ b/remote-processor/Message.cpp @@ -28,7 +28,9 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "Message.h" +#include "Socket.h" #include "Iterator.hpp" +#include #include #include #include @@ -125,8 +127,10 @@ size_t CMessage::getRemainingDataSize() const } // Send/Receive -CMessage::Result CMessage::serialize(asio::ip::tcp::socket &socket, bool bOut, string &strError) +CMessage::Result CMessage::serialize(Socket &&socket, bool bOut, string &strError) { + asio::ip::tcp::socket &asioSocket = socket.get(); + if (bOut) { asio::error_code ec; @@ -142,7 +146,7 @@ CMessage::Result CMessage::serialize(asio::ip::tcp::socket &socket, bool bOut, s // First send sync word uint16_t uiSyncWord = SYNC_WORD; - if (!asio::write(socket, asio::buffer(&uiSyncWord, sizeof(uiSyncWord)), ec)) { + if (!asio::write(asioSocket, asio::buffer(&uiSyncWord, sizeof(uiSyncWord)), ec)) { if (ec == asio::error::eof) { return peerDisconnected; @@ -153,21 +157,21 @@ CMessage::Result CMessage::serialize(asio::ip::tcp::socket &socket, bool bOut, s // Size uint32_t uiSize = (uint32_t)(sizeof(_ucMsgId) + getMessageDataSize()); - if (!asio::write(socket, asio::buffer(&uiSize, sizeof(uiSize)), ec)) { + if (!asio::write(asioSocket, asio::buffer(&uiSize, sizeof(uiSize)), ec)) { strError += string("Size write failed: ") + ec.message(); return error; } // Msg Id - if (!asio::write(socket, asio::buffer(&_ucMsgId, sizeof(_ucMsgId)), ec)) { + if (!asio::write(asioSocket, asio::buffer(&_ucMsgId, sizeof(_ucMsgId)), ec)) { strError += string("Msg write failed: ") + ec.message(); return error; } // Data - if (!asio::write(socket, asio::buffer(mData), ec)) { + if (!asio::write(asioSocket, asio::buffer(mData), ec)) { strError = string("Data write failed: ") + ec.message(); return error; @@ -176,7 +180,7 @@ CMessage::Result CMessage::serialize(asio::ip::tcp::socket &socket, bool bOut, s // Checksum uint8_t ucChecksum = computeChecksum(); - if (!asio::write(socket, asio::buffer(&ucChecksum, sizeof(ucChecksum)), ec)) { + if (!asio::write(asioSocket, asio::buffer(&ucChecksum, sizeof(ucChecksum)), ec)) { strError = string("Checksum write failed: ") + ec.message(); return error; @@ -187,7 +191,7 @@ CMessage::Result CMessage::serialize(asio::ip::tcp::socket &socket, bool bOut, s uint16_t uiSyncWord = 0; asio::error_code ec; - if (!asio::read(socket, asio::buffer(&uiSyncWord, sizeof(uiSyncWord)), ec)) { + if (!asio::read(asioSocket, asio::buffer(&uiSyncWord, sizeof(uiSyncWord)), ec)) { strError = string("Sync read failed: ") + ec.message(); if (ec == asio::error::eof) { return peerDisconnected; @@ -205,13 +209,13 @@ CMessage::Result CMessage::serialize(asio::ip::tcp::socket &socket, bool bOut, s // Size uint32_t uiSize = 0; - if (!asio::read(socket, asio::buffer(&uiSize, sizeof(uiSize)), ec)) { + if (!asio::read(asioSocket, asio::buffer(&uiSize, sizeof(uiSize)), ec)) { strError = string("Size read failed: ") + ec.message(); return error; } // Msg Id - if (!asio::read(socket, asio::buffer(&_ucMsgId, sizeof(_ucMsgId)), ec)) { + if (!asio::read(asioSocket, asio::buffer(&_ucMsgId, sizeof(_ucMsgId)), ec)) { strError = string("Msg id read failed: ") + ec.message(); return error; } @@ -222,7 +226,7 @@ CMessage::Result CMessage::serialize(asio::ip::tcp::socket &socket, bool bOut, s allocateData(uiSize - sizeof(_ucMsgId)); // Data receive - if (!asio::read(socket, asio::buffer(mData), ec)) { + if (!asio::read(asioSocket, asio::buffer(mData), ec)) { strError = string("Data read failed: ") + ec.message(); return error; } @@ -230,7 +234,7 @@ CMessage::Result CMessage::serialize(asio::ip::tcp::socket &socket, bool bOut, s // Checksum uint8_t ucChecksum = 0; - if (!asio::read(socket, asio::buffer(&ucChecksum, sizeof(ucChecksum)), ec)) { + if (!asio::read(asioSocket, asio::buffer(&ucChecksum, sizeof(ucChecksum)), ec)) { strError = string("Checksum read failed: ") + ec.message(); return error; } diff --git a/remote-processor/Message.h b/remote-processor/Message.h index ead2743c2..2a596f113 100644 --- a/remote-processor/Message.h +++ b/remote-processor/Message.h @@ -30,12 +30,14 @@ #pragma once #include "NonCopyable.hpp" -#include +#include #include #include #include +class Socket; + class REMOTE_PROCESSOR_EXPORT CMessage : private utility::NonCopyable { public: @@ -69,7 +71,7 @@ class REMOTE_PROCESSOR_EXPORT CMessage : private utility::NonCopyable * peerDisconnected if the peer disconnected before the first socket access. * error if the message could not be read/write for any other reason */ - Result serialize(asio::ip::tcp::socket &socket, bool bOut, std::string &strError); + Result serialize(Socket &&socket, bool bOut, std::string &strError); protected: // Msg Id diff --git a/remote-processor/RemoteProcessorServer.cpp b/remote-processor/RemoteProcessorServer.cpp index 4fac086c1..d3fefddcb 100644 --- a/remote-processor/RemoteProcessorServer.cpp +++ b/remote-processor/RemoteProcessorServer.cpp @@ -35,6 +35,7 @@ #include "RequestMessage.h" #include "AnswerMessage.h" #include "RemoteCommandHandler.h" +#include "Socket.h" using std::string; @@ -126,7 +127,7 @@ void CRemoteProcessorServer::handleNewConnection(IRemoteCommandHandler &commandH string strError; ///// Receive command CRequestMessage::Result res; - res = requestMessage.serialize(_socket, false, strError); + res = requestMessage.serialize(Socket(_socket), false, strError); switch (res) { case CRequestMessage::error: diff --git a/remote-processor/Socket.h b/remote-processor/Socket.h new file mode 100644 index 000000000..020750bad --- /dev/null +++ b/remote-processor/Socket.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2016, Intel Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. 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. + * + * 3. Neither the name of the copyright holder 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 + +/** Wraps and hides asio::ip::tcp::socket + * + * asio::ip::tcp::socket cannot be forward-declared because it is an + * inner-class. This class wraps the asio class in order for it to be + * forward-declared and avoid it to leak in client interfaces. + */ +class Socket +{ +public: + Socket(asio::ip::tcp::socket &socket) : mSocket(socket) {} + + asio::ip::tcp::socket &get() { return mSocket; } + +private: + asio::ip::tcp::socket &mSocket; +}; diff --git a/test/functional-tests-legacy/CMakeLists.txt b/test/functional-tests-legacy/CMakeLists.txt index 9fe4c52c5..2eb172472 100644 --- a/test/functional-tests-legacy/CMakeLists.txt +++ b/test/functional-tests-legacy/CMakeLists.txt @@ -26,7 +26,9 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -if(BUILD_TESTING) +# This test suite relies on remote-process - which isn't available when +# networking is disabled +if(BUILD_TESTING AND NETWORKING) find_package(PythonInterp 2 REQUIRED) set(PFW_ROOT ${PROJECT_BINARY_DIR}/tmp/test-parameters) diff --git a/test/test-platform/CMakeLists.txt b/test/test-platform/CMakeLists.txt index cef284f27..533de3c5a 100644 --- a/test/test-platform/CMakeLists.txt +++ b/test/test-platform/CMakeLists.txt @@ -26,11 +26,15 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -add_executable(test-platform - main.cpp - TestPlatform.cpp) +if(NETWORKING) + add_executable(test-platform + main.cpp + TestPlatform.cpp) -target_link_libraries(test-platform - PRIVATE parameter pfw_utility remote-processor) + target_link_libraries(test-platform + PRIVATE parameter pfw_utility remote-processor) + # Workaround because asio is still leaking to test-platform + target_link_libraries(test-platform PRIVATE asio) -install(TARGETS test-platform RUNTIME DESTINATION bin) + install(TARGETS test-platform RUNTIME DESTINATION bin) +endif()