From: Colm Donelan Date: Mon, 9 Sep 2019 10:59:08 +0000 (+0100) Subject: IVGCVSW-3720 Start a UDS server that accepts connections. X-Git-Tag: submit/tizen/20200316.035456~290 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=a85e215dd1b027c5ef88621d1b4d5f6e078605da;p=platform%2Fupstream%2Farmnn.git IVGCVSW-3720 Start a UDS server that accepts connections. * Add a CLI paramter to the Gatord mock client to specify a namespace. * Open a listening socket on that namespace. * Wait for one connection on the socket. Signed-off-by: Colm Donelan Change-Id: Ic85b4defd5ad2010bb255472c030a91a23cec1d9 --- diff --git a/CMakeLists.txt b/CMakeLists.txt index b29a709..217c420 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -825,6 +825,8 @@ if(BUILD_GATORD_MOCK) tests/profiling/GatordMockMain.cpp tests/profiling/CommandLineProcessor.hpp tests/profiling/CommandLineProcessor.cpp + tests/profiling/GatordMockService.hpp + tests/profiling/GatordMockService.cpp ) include_directories( ${Boost_INCLUDE_DIRS} ) diff --git a/tests/profiling/CommandLineProcessor.cpp b/tests/profiling/CommandLineProcessor.cpp index 6affbbe..1b431c0 100644 --- a/tests/profiling/CommandLineProcessor.cpp +++ b/tests/profiling/CommandLineProcessor.cpp @@ -21,7 +21,11 @@ bool CommandLineProcessor::ProcessCommandLine(int argc, char *argv[]) po::options_description desc("Options"); try { - desc.add_options()("help,h", "Display help messages"); + desc.add_options() + ("help,h", "Display help messages") + ("namespace,n", po::value(&m_UdsNamespace)->default_value("gatord_namespace"), + "The Unix domain socket namespace this server will bind to.\n" + "This will always be prepended with \\0 to use the abstract namespace"); } catch (const std::exception& e) { @@ -34,7 +38,7 @@ bool CommandLineProcessor::ProcessCommandLine(int argc, char *argv[]) { po::store(po::parse_command_line(argc, argv, desc), vm); - if (vm.count("help") || argc <= 1) + if (vm.count("help")) { std::cout << "Simulate a Gatord server to interact with ArmNN external profiling." << std::endl; std::cout << std::endl; diff --git a/tests/profiling/CommandLineProcessor.hpp b/tests/profiling/CommandLineProcessor.hpp index 441d7cd..a7e43ad 100644 --- a/tests/profiling/CommandLineProcessor.hpp +++ b/tests/profiling/CommandLineProcessor.hpp @@ -4,6 +4,8 @@ // #pragma once +#include + namespace armnn { @@ -12,12 +14,22 @@ namespace gatordmock // Parses the command line to extract: // +// +/** + * Use Boost program options to process the command line. + * -h or --help to print the options. + * -n or --namespace to specify the UDS namespace that the server will be listening on. + */ class CommandLineProcessor { public: bool ProcessCommandLine(int argc, char *argv[]); + std::string GetUdsNamespace() { return m_UdsNamespace; } + +private: + std::string m_UdsNamespace; }; } // namespace gatordmock diff --git a/tests/profiling/GatordMockMain.cpp b/tests/profiling/GatordMockMain.cpp index 91fa907..b8edeb2 100644 --- a/tests/profiling/GatordMockMain.cpp +++ b/tests/profiling/GatordMockMain.cpp @@ -4,8 +4,7 @@ // #include "CommandLineProcessor.hpp" - -#include +#include "GatordMockService.hpp" int main(int argc, char *argv[]) { @@ -14,5 +13,15 @@ int main(int argc, char *argv[]) { return EXIT_FAILURE; } + armnn::gatordmock::GatordMockService mockService; + if (!mockService.OpenListeningSocket(cmdline.GetUdsNamespace())) + { + return EXIT_FAILURE; + } + int clientFd = mockService.BlockForOneClient(); + if (-1 == clientFd) + { + return EXIT_FAILURE; + } return EXIT_SUCCESS; } diff --git a/tests/profiling/GatordMockService.cpp b/tests/profiling/GatordMockService.cpp new file mode 100644 index 0000000..c774ab0 --- /dev/null +++ b/tests/profiling/GatordMockService.cpp @@ -0,0 +1,71 @@ +// +// Copyright © 2019 Arm Ltd. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#include "GatordMockService.hpp" + +#include +#include +#include +#include +#include +#include + +namespace armnn +{ + +namespace gatordmock +{ + + +bool GatordMockService::OpenListeningSocket(std::string udsNamespace) +{ + m_ListeningSocket = socket(PF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0); + if (-1 == m_ListeningSocket) + { + std::cerr << ": Socket construction failed: " << strerror(errno) << std::endl; + return false; + } + + sockaddr_un udsAddress; + memset(&udsAddress, 0, sizeof(sockaddr_un)); + // We've set the first element of sun_path to be 0, skip over it and copy the namespace after it. + memcpy(udsAddress.sun_path + 1, udsNamespace.c_str(), strlen(udsNamespace.c_str())); + udsAddress.sun_family = AF_UNIX; + + // Bind the socket to the UDS namespace. + if (-1 == bind(m_ListeningSocket, reinterpret_cast(&udsAddress), sizeof(sockaddr_un))) + { + std::cerr << ": Binding on socket failed: " << strerror(errno) << std::endl; + return false; + } + // Listen for 1 connection. + if (-1 == listen(m_ListeningSocket, 1)) + { + std::cerr << ": Listen call on socket failed: " << strerror(errno) << std::endl; + return false; + } + std::cout << "Bound to UDS namespace: \\0" << udsNamespace << std::endl; + return true; +} + +int GatordMockService::BlockForOneClient() +{ + std::cout << "Waiting for client connection." << std::endl; + + int accepted = accept4(m_ListeningSocket, nullptr, nullptr, SOCK_CLOEXEC); + if (-1 == accepted) + { + std::cerr << ": Failure when waiting for a client connection: " << strerror(errno) << std::endl; + return -1; + } + + std::cout << "Client connection established." << std::endl; + return accepted; +} + + +} // namespace gatordmock + +} // namespace armnn diff --git a/tests/profiling/GatordMockService.hpp b/tests/profiling/GatordMockService.hpp new file mode 100644 index 0000000..c19e710 --- /dev/null +++ b/tests/profiling/GatordMockService.hpp @@ -0,0 +1,50 @@ +// +// Copyright © 2019 Arm Ltd. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#pragma once + +#include + +namespace armnn +{ + +namespace gatordmock +{ + + +/** + * A class that implements a Mock Gatord server. It will listen on a specified Unix domain socket (UDS) + * namespace for client connections. + */ +class GatordMockService +{ +public: + + /** + * Establish the Unix domain socket and set it to listen for connections. + * + * @param udsNamespace the namespace (socket address) associated with the listener. + * @return true only if the socket has been correctly setup. + */ + bool OpenListeningSocket(std::string udsNamespace); + + /** + * Block waiting to accept one client to connect to the UDS. + * + * @return the file descriptor of the client connection. + */ + int BlockForOneClient(); + +private: + + int m_ListeningSocket; +}; + + +} // namespace gatordmock + +} // namespace armnn + +