Add a simulator control client 97/174797/3
authorIgor Kotrasinski <i.kotrasinsk@partner.samsung.com>
Fri, 15 Dec 2017 14:43:55 +0000 (15:43 +0100)
committerTomasz Swierczek <t.swierczek@samsung.com>
Thu, 12 Apr 2018 06:59:58 +0000 (06:59 +0000)
Change-Id: I8ef2c5543f9e5723b614fd0d191b58894c2e4478
Signed-off-by: Igor Kotrasinski <i.kotrasinsk@partner.samsung.com>
simulatordaemon/CMakeLists.txt
simulatordaemon/daemonctl/CMakeLists.txt [new file with mode: 0644]
simulatordaemon/daemonctl/inc/SimulatorDaemonCtl.h [new file with mode: 0644]
simulatordaemon/daemonctl/inc/handlers/DebugPortHandler.h [new file with mode: 0644]
simulatordaemon/daemonctl/src/SimulatorDaemonCtl.cpp [new file with mode: 0644]
simulatordaemon/daemonctl/src/handlers/DebugPortHandler.cpp [new file with mode: 0644]
simulatordaemon/inc/UUIDUtils.h
simulatordaemon/src/UUIDUtils.cpp

index f223a11..e842dc2 100644 (file)
@@ -110,7 +110,7 @@ TARGET_LINK_LIBRARIES(${TARGET_TEF_SIMULATOR_DAEMON}
     ${DAEMON_DEPS_LIBRARIES}
     ${TARGET_TEF_SIMULATOR_LOG}
     ${TARGET_TEF_SIMULATOR_OSAL}
-    boost_system boost_filesystem
+    boost_system boost_filesystem boost_regex
     )
 
 INSTALL(TARGETS ${TARGET_TEF_SIMULATOR_DAEMON} DESTINATION ${BIN_DIR})
@@ -118,3 +118,5 @@ INSTALL(TARGETS ${TARGET_TEF_SIMULATOR_DAEMON} DESTINATION ${BIN_DIR})
 INSTALL(DIRECTORY DESTINATION ${BUILD_ROOT}${TASTORE_DIR})
 INSTALL(DIRECTORY DESTINATION ${BUILD_ROOT}${EXTRACT_DIR})
 INSTALL(DIRECTORY DESTINATION ${BUILD_ROOT}${STORAGE_DIR})
+
+ADD_SUBDIRECTORY(daemonctl)
diff --git a/simulatordaemon/daemonctl/CMakeLists.txt b/simulatordaemon/daemonctl/CMakeLists.txt
new file mode 100644 (file)
index 0000000..544f843
--- /dev/null
@@ -0,0 +1,40 @@
+# Copyright (c) 2018 Samsung Electronics Co., Ltd All Rights Reserved
+#
+#    Licensed under the Apache License, Version 2.0 (the "License");
+#    you may not use this file except in compliance with the License.
+#    You may obtain a copy of the License at
+#
+#        http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS,
+#    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#    See the License for the specific language governing permissions and
+#    limitations under the License.
+#
+# @file
+# @author  Igor Kotrasinski (i.kotrasinsk@partner.samsung.com)
+# @brief   CMakeLists for tef-simulator daemon control binary
+#
+
+SET(DAEMONCTL_SOURCES
+        ${DAEMONCTL_PATH}/src/SimulatorDaemonCtl.cpp
+        ${DAEMONCTL_PATH}/src/handlers/DebugPortHandler.cpp
+        ${DAEMON_PATH}/src/UUIDUtils.cpp
+    )
+
+ADD_EXECUTABLE(${TARGET_TEF_SIMULATOR_DAEMONCTL}
+    ${DAEMONCTL_SOURCES}
+    )
+
+INCLUDE_DIRECTORIES(
+        ${DAEMON_PATH}/inc
+        ${DAEMONCTL_PATH}/inc
+        ${DAEMONCTL_PATH}/inc/handlers
+    )
+
+TARGET_LINK_LIBRARIES(${TARGET_TEF_SIMULATOR_DAEMONCTL}
+    boost_system boost_program_options boost_regex
+    )
+
+INSTALL(TARGETS ${TARGET_TEF_SIMULATOR_DAEMONCTL} DESTINATION ${BIN_DIR})
diff --git a/simulatordaemon/daemonctl/inc/SimulatorDaemonCtl.h b/simulatordaemon/daemonctl/inc/SimulatorDaemonCtl.h
new file mode 100644 (file)
index 0000000..eb8253a
--- /dev/null
@@ -0,0 +1,37 @@
+/**
+ * Copyright (c) 2015-2018 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+
+/**
+ * @file
+ * @author Igor Kotrasinski (i.kotrasinsk@partner.samsung.com)
+ * @brief  Common daemonctl code and main method
+ */
+
+#ifndef _SIMULATOR_DAEMON_CTL_H
+#define _SIMULATOR_DAEMON_CTL_H
+
+#include <map>
+#include <string>
+
+#include "ControlCommand.h"
+
+extern std::map<ControlReplyStatus, std::string> controlErrors;
+int communicateWithDaemon(ControlCommand outHeader,
+                         void *outBuf, size_t outBufSize,
+                         ControlCommand inHeader,
+                         void *inBuf, size_t inBufSize);
+
+#endif /* _SIMULATOR_DAEMON_CTL_H */
diff --git a/simulatordaemon/daemonctl/inc/handlers/DebugPortHandler.h b/simulatordaemon/daemonctl/inc/handlers/DebugPortHandler.h
new file mode 100644 (file)
index 0000000..863ab5b
--- /dev/null
@@ -0,0 +1,48 @@
+/**
+ * Copyright (c) 2015-2018 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+
+/**
+ * @file
+ * @author Igor Kotrasinski (i.kotrasinsk@partner.samsung.com)
+ * @brief  Common daemonctl code and main method
+ */
+
+#include <string>
+#include <boost/program_options/options_description.hpp>
+#include <boost/program_options/variables_map.hpp>
+#include "tee_client_api.h"
+#include "ControlCommand.h"
+
+#ifndef _DEBUG_PORT_HANDLER_H
+#define _DEBUG_PORT_HANDLER_H
+
+class DebugPortHandler
+{
+public:
+       DebugPortHandler();
+       int handle(int argc, char *argv[]);
+private:
+       boost::program_options::options_description m_desc;
+       boost::program_options::variables_map m_opts;
+       void readOptions(int argc, char *argv[]);
+       void readOptionsPermissively(int argc, char *argv[]);
+       void parseCommandlineArgs(int argc, char *argv[]);
+       void checkExactlyOneMainFlag();
+       bool handleCommandlineArgs(
+               int argc, char *argv[], SetPortControlCommand &cmd);
+};
+
+#endif /* _DEBUG_PORT_HANDLER_H */
diff --git a/simulatordaemon/daemonctl/src/SimulatorDaemonCtl.cpp b/simulatordaemon/daemonctl/src/SimulatorDaemonCtl.cpp
new file mode 100644 (file)
index 0000000..65b8686
--- /dev/null
@@ -0,0 +1,93 @@
+/**
+ * Copyright (c) 2015-2018 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+
+/**
+ * @file
+ * @author Igor Kotrasinski (i.kotrasinsk@partner.samsung.com)
+ * @brief  Common daemonctl code and main method
+ */
+
+#include <iostream>
+#include <cstdint>
+#include <cstdlib>
+#include <string>
+#include <map>
+#include <boost/system/system_error.hpp>
+#include <boost/asio.hpp>
+#include <boost/asio/local/stream_protocol.hpp>
+
+#include "tee_client_api.h"
+
+#include <config.h>
+#include "ControlCommand.h"
+#include "DebugPortHandler.h"
+#include "SimulatorDaemonCtl.h"
+
+#define USAGE_STRING                                           \
+       "USAGE: tef-simulator-ctl <command> <options>\n"        \
+       "Available commands:\n"                                 \
+       "\n"                                                    \
+       "debugport - set a gdb debugging port for a TA UUID\n"
+
+
+std::map<ControlReplyStatus, std::string> controlErrors = {
+       {CTL_REPLY_SUCCESS, "Success"},
+       {CTL_REPLY_TA_NOT_FOUND, "TA not found"},
+       {CTL_REPLY_INTERNAL_ERROR, "Internal error"},
+};
+
+static void printUsage() {
+       printf(USAGE_STRING);
+}
+
+int communicateWithDaemon(ControlCommand outHeader,
+                         void *outBuf, size_t outBufSize,
+                         ControlCommand inHeader,
+                         void *inBuf, size_t inBufSize)
+{
+       boost::asio::io_service io;
+       boost::asio::local::stream_protocol::socket sock(io);
+
+       try {
+               sock.connect(SIMDAEMON_CTL_PATH);
+               boost::asio::write(sock, boost::asio::buffer(&outHeader,
+                                                            sizeof(outHeader)));
+               boost::asio::write(sock, boost::asio::buffer(outBuf, outBufSize));
+               boost::asio::read(sock, boost::asio::buffer(&inHeader,
+                                                           sizeof(inHeader)));
+               boost::asio::read(sock, boost::asio::buffer(inBuf, inBufSize));
+       } catch (boost::system::system_error &e) {
+               std::cerr << "Failed to communicate with simulator daemon:"
+                         << e.what() << std::endl;
+               return 1;
+       }
+       return 0;
+}
+
+int main(int argc, char *argv[])
+{
+       if (argc < 2) {
+               printUsage();
+               return 1;
+       }
+       if (strcmp(argv[1], "debugport") == 0) {
+               DebugPortHandler handler{};
+               handler.handle(argc - 1, argv + 1);
+       } else {
+               printUsage();
+               return 1;
+       }
+}
diff --git a/simulatordaemon/daemonctl/src/handlers/DebugPortHandler.cpp b/simulatordaemon/daemonctl/src/handlers/DebugPortHandler.cpp
new file mode 100644 (file)
index 0000000..2d7bb0f
--- /dev/null
@@ -0,0 +1,154 @@
+/**
+ * Copyright (c) 2015-2018 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+
+/**
+ * @file
+ * @author Igor Kotrasinski (i.kotrasinsk@partner.samsung.com)
+ * @brief  Common daemonctl code and main method
+ */
+
+#include <cstdio>
+#include <iostream>
+#include <cstdint>
+#include <string>
+#include <sstream>
+#include <vector>
+
+#include <boost/program_options/cmdline.hpp>
+#include <boost/program_options/options_description.hpp>
+#include <boost/program_options/variables_map.hpp>
+#include <boost/program_options/parsers.hpp>
+#include <boost/algorithm/string/join.hpp>
+#include <boost/regex.hpp>
+
+#include "UUIDUtils.h"
+#include "ControlCommand.h"
+#include "SimulatorDaemonCtl.h"
+#include "DebugPortHandler.h"
+
+
+DebugPortHandler::DebugPortHandler()
+       : m_desc("Debugport options")
+{
+       m_desc.add_options()
+               ("help,h", "Display this help message")
+               ("uuid,u", boost::program_options::value<std::string>(),
+                "TA UUID to set port for")
+               ("port,p", boost::program_options::value<int32_t>(),
+                "Port number");
+}
+
+void DebugPortHandler::readOptions(int argc, char *argv[]) {
+       boost::program_options::store(
+               boost::program_options::parse_command_line(
+                       argc, argv, m_desc), m_opts);
+       boost::program_options::notify(m_opts);
+}
+
+void DebugPortHandler::readOptionsPermissively(int argc, char *argv[])
+{
+       auto parser = boost::program_options::command_line_parser(argc, argv)
+                       .options(m_desc)
+                       .allow_unregistered()
+                       .run();
+       boost::program_options::store(parser, m_opts);
+       boost::program_options::notify(m_opts);
+}
+
+void DebugPortHandler::checkExactlyOneMainFlag()
+{
+       std::vector<std::string> mainOptions = { "port" };
+       auto optionCount = [this](std::string &s) { return m_opts.count(s) > 0; };
+       bool mainOptionCount = std::count_if(mainOptions.begin(),
+                                            mainOptions.end(),
+                                            optionCount);
+       if (mainOptionCount != 1) {
+               std::stringstream errStr;
+               errStr << "Expected exactly one of:";
+               for (std::string option: mainOptions)
+                       errStr << " --" << option;
+               throw boost::program_options::error(errStr.str());
+       }
+}
+
+void DebugPortHandler::parseCommandlineArgs(
+               int argc, char *argv[])
+{
+       /* Avoid complaining about bad parameters if --help was passed */
+       readOptionsPermissively(argc, argv);
+       if (m_opts.count("help"))
+               return;
+       checkExactlyOneMainFlag();
+       if (!m_opts.count("uuid"))
+               throw boost::program_options::required_option("uuid");
+}
+
+bool DebugPortHandler::handleCommandlineArgs(
+               int argc, char *argv[], SetPortControlCommand &cmd)
+{
+       int ret;
+
+       parseCommandlineArgs(argc, argv);
+       if (m_opts.count("help")) {
+               std::cout << m_desc;
+               return false;
+       }
+
+       if (m_opts.count("port")) {
+               cmd.port = m_opts["port"].as<int32_t>();
+               if (cmd.port < 0)
+                       throw boost::program_options::error(
+                                       "Port number cannot be negative!");
+       }
+
+       TEEC_UUID taUuid;
+       ret = uuidStringToUuid(m_opts["uuid"].as<std::string>(), taUuid);
+       if (ret)
+               throw boost::program_options::error(
+                       "Invalid UUID format, expected x{8}-x{4}-x{4}-x{4}-x{12}");
+       cmd.uuid = taUuid;
+       return true;
+}
+
+int DebugPortHandler::handle(int argc, char *argv[])
+{
+       int ret;
+       bool shouldCommunicate;
+       SetPortControlCommand cmd;
+       SetPortControlCommandReply reply;
+
+       try {
+               shouldCommunicate = handleCommandlineArgs(argc, argv, cmd);
+       } catch (boost::program_options::error &e) {
+               std::cerr << "Commandline parsing error: " << e.what() << std::endl;
+               std::cerr << m_desc;
+               return 1;
+       }
+       if (!shouldCommunicate)
+               return 0;
+
+       ret = communicateWithDaemon(CTL_SET_PORT, &cmd, sizeof(cmd),
+                                   CTL_SET_PORT_REPLY, &reply, sizeof(reply));
+       if (ret)
+               return ret;
+
+       if (reply.status != CTL_REPLY_SUCCESS) {
+               std::cerr << "Command failed: " << controlErrors[reply.status] << std::endl;
+               return 1;
+       }
+
+       return 0;
+}
index 9a6083e..f17b923 100644 (file)
@@ -27,6 +27,7 @@
 #include "tee_client_api.h"
 
 std::string UUIDToString(TEEC_UUID uuid);
+int uuidStringToUuid(std::string uuidStr, TEEC_UUID &uuid);
 
 class UUIDComparator {
 public:
index fd6ef7a..366f9e1 100644 (file)
@@ -23,6 +23,8 @@
 #include <string>
 #include <sstream>
 #include <iomanip>
+#include <boost/regex.hpp>
+#include <boost/algorithm/string/join.hpp>
 
 #include "tee_client_api.h"
 
@@ -43,3 +45,37 @@ std::string UUIDToString(TEEC_UUID uuid) {
        }
        return strStream.str();
 }
+
+
+int uuidStringToUuid(std::string uuidStr, TEEC_UUID &uuid)
+{
+       bool formatIsCorrect;
+
+       /* Format as specified by RFC 4122 */
+       auto hexGroup = [](int n) { return "([0-9a-fA-F]{" + std::to_string(n) + "})"; };
+       std::vector<std::string> uuidRegexParts = {
+               hexGroup(8),
+               hexGroup(4),
+               hexGroup(4),
+               hexGroup(4),
+               hexGroup(12),
+       };
+       boost::regex uuidRegex { boost::algorithm::join(uuidRegexParts, "-") };
+       boost::smatch uuidParts;
+
+       formatIsCorrect = boost::regex_match(uuidStr, uuidParts, uuidRegex);
+       if (!formatIsCorrect)
+               return 1;
+
+       auto toHex = [](std::string part) { return std::strtol(part.c_str(), nullptr, 16); };
+       uuid.timeLow = toHex(std::string(uuidParts[1]));
+       uuid.timeMid = toHex(std::string(uuidParts[2]));
+       uuid.timeHiAndVersion = toHex(std::string(uuidParts[3]));
+
+       std::string seqPart = std::string(uuidParts[4]) + std::string(uuidParts[5]);
+       for (int i = 0; i < 8 ; i++) {
+               std::string seqSegment = seqPart.substr(i * 2, 2);
+               uuid.clockSeqAndNode[i] = toHex(std::string(seqSegment));
+       }
+       return 0;
+}