summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorYong Li <yong.b.li@linux.intel.com>2018-01-04 08:59:03 +0300
committerYong Li <yong.b.li@linux.intel.com>2018-01-18 08:32:37 +0300
commite31fc4f8e8e2870745ee82d38ba1f79480001f0b (patch)
tree04b92a9eb7ded075763e0ccf2b4bb18736b96244 /tools
parent592c7b91e2c4e307bdc18febcd38257da2049791 (diff)
downloadprovingground-e31fc4f8e8e2870745ee82d38ba1f79480001f0b.tar.xz
Add prop_wait tool
OPENBMC2-919 Add a tool to query the dbus property, to check if it is the expected value. Used by chassis/power control Change-Id: Ia5d421e4ca1c9e699b881ec007020359b1411bbf Signed-off-by: Yong Li <yong.b.li@linux.intel.com>
Diffstat (limited to 'tools')
-rw-r--r--tools/prop_wait/.clang-format98
-rw-r--r--tools/prop_wait/CMakeLists.txt24
-rw-r--r--tools/prop_wait/include/argument.hpp48
-rw-r--r--tools/prop_wait/src/argument.cpp100
-rw-r--r--tools/prop_wait/src/prop_wait.cpp151
5 files changed, 421 insertions, 0 deletions
diff --git a/tools/prop_wait/.clang-format b/tools/prop_wait/.clang-format
new file mode 100644
index 0000000..e949c5e
--- /dev/null
+++ b/tools/prop_wait/.clang-format
@@ -0,0 +1,98 @@
+---
+BasedOnStyle: Google
+AccessModifierOffset: -1
+AlignAfterOpenBracket: Align
+AlignConsecutiveAssignments: false
+AlignConsecutiveDeclarations: false
+AlignEscapedNewlinesLeft: true
+AlignOperands: true
+AlignTrailingComments: true
+AllowAllParametersOfDeclarationOnNextLine: true
+AllowShortBlocksOnASingleLine: false
+AllowShortCaseLabelsOnASingleLine: false
+AllowShortFunctionsOnASingleLine: All
+AllowShortIfStatementsOnASingleLine: true
+AllowShortLoopsOnASingleLine: true
+AlwaysBreakAfterDefinitionReturnType: None
+AlwaysBreakAfterReturnType: None
+AlwaysBreakBeforeMultilineStrings: true
+AlwaysBreakTemplateDeclarations: true
+BinPackArguments: true
+BinPackParameters: true
+BraceWrapping:
+ AfterClass: false
+ AfterControlStatement: false
+ AfterEnum: false
+ AfterFunction: false
+ AfterNamespace: false
+ AfterObjCDeclaration: false
+ AfterStruct: false
+ AfterUnion: false
+ BeforeCatch: false
+ BeforeElse: false
+ IndentBraces: false
+BreakBeforeBinaryOperators: None
+BreakBeforeBraces: Attach
+BreakBeforeTernaryOperators: true
+BreakConstructorInitializersBeforeComma: false
+ColumnLimit: 80
+CommentPragmas: '^ IWYU pragma:'
+ConstructorInitializerAllOnOneLineOrOnePerLine: true
+ConstructorInitializerIndentWidth: 4
+ContinuationIndentWidth: 4
+Cpp11BracedListStyle: true
+DerivePointerAlignment: true
+DisableFormat: false
+ExperimentalAutoDetectBinPacking: false
+ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
+IncludeCategories:
+
+ - Regex: '^[<"](crow)'
+ Priority: 5
+ - Regex: '^[<"](boost)'
+ Priority: 6
+ - Regex: '^[<"](gtest|gmock)'
+ Priority: 7
+ - Regex: '^<.*\.h>'
+ Priority: 1
+ - Regex: '^<.*\.hpp>'
+ Priority: 2
+ - Regex: '^<.*'
+ Priority: 3
+ - Regex: '.*'
+ Priority: 4
+IndentCaseLabels: true
+IndentWidth: 4
+IndentWrappedFunctionNames: false
+KeepEmptyLinesAtTheStartOfBlocks: false
+MacroBlockBegin: ''
+MacroBlockEnd: ''
+MaxEmptyLinesToKeep: 1
+NamespaceIndentation: None
+ObjCBlockIndentWidth: 2
+ObjCSpaceAfterProperty: false
+ObjCSpaceBeforeProtocolList: false
+PenaltyBreakBeforeFirstCallParameter: 1
+PenaltyBreakComment: 300
+PenaltyBreakFirstLessLess: 120
+PenaltyBreakString: 1000
+PenaltyExcessCharacter: 1000000
+PenaltyReturnTypeOnItsOwnLine: 200
+PointerAlignment: Left
+ReflowComments: true
+SortIncludes: true
+SpaceAfterCStyleCast: false
+SpaceBeforeAssignmentOperators: true
+SpaceBeforeParens: ControlStatements
+SpaceInEmptyParentheses: false
+SpacesBeforeTrailingComments: 2
+SpacesInAngles: false
+SpacesInContainerLiterals: true
+SpacesInCStyleCastParentheses: false
+SpacesInParentheses: false
+SpacesInSquareBrackets: false
+Standard: Auto
+TabWidth: 8
+UseTab: Never
+...
+
diff --git a/tools/prop_wait/CMakeLists.txt b/tools/prop_wait/CMakeLists.txt
new file mode 100644
index 0000000..78ccff1
--- /dev/null
+++ b/tools/prop_wait/CMakeLists.txt
@@ -0,0 +1,24 @@
+cmake_minimum_required(VERSION 2.8.10 FATAL_ERROR)
+project(prop_wait CXX)
+set(CMAKE_CXX_STANDARD 14)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+
+include(GNUInstallDirs)
+
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
+
+set(SRC_FILES
+ src/prop_wait.cpp
+ src/argument.cpp
+)
+
+# import phosphor-logging
+find_package(PkgConfig REQUIRED)
+pkg_check_modules(LOGGING phosphor-logging REQUIRED)
+include_directories(${LOGGING_INCLUDE_DIRS})
+link_directories(${LOGGING_LIBRARY_DIRS})
+
+add_executable(${PROJECT_NAME} ${SRC_FILES})
+target_link_libraries(${PROJECT_NAME} ${LOGGING_LIBRARIES})
+
+install (TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR}) \ No newline at end of file
diff --git a/tools/prop_wait/include/argument.hpp b/tools/prop_wait/include/argument.hpp
new file mode 100644
index 0000000..19391df
--- /dev/null
+++ b/tools/prop_wait/include/argument.hpp
@@ -0,0 +1,48 @@
+/**
+ * Copyright (c) 2017 Intel Corporation
+ *
+ * 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.
+ */
+
+#pragma once
+
+#include <getopt.h>
+#include <map>
+#include <string>
+
+/**
+ * Parses command line arguments.
+ */
+class ArgumentParser
+{
+ public:
+ ArgumentParser(int argc, char** argv);
+ ArgumentParser() = delete;
+ ArgumentParser(const ArgumentParser&) = delete;
+ ArgumentParser(ArgumentParser&&) = default;
+ ArgumentParser& operator=(const ArgumentParser&) = delete;
+ ArgumentParser& operator=(ArgumentParser&&) = default;
+ ~ArgumentParser() = default;
+ const std::string& operator[](const std::string& opt);
+
+ static void usage(char** argv);
+
+ static const std::string true_string;
+ static const std::string empty_string;
+
+ private:
+ std::map<const std::string, std::string> arguments;
+
+ static const option options[];
+ static const char* optionstr;
+};
diff --git a/tools/prop_wait/src/argument.cpp b/tools/prop_wait/src/argument.cpp
new file mode 100644
index 0000000..8e5f799
--- /dev/null
+++ b/tools/prop_wait/src/argument.cpp
@@ -0,0 +1,100 @@
+/**
+ * Copyright (c) 2017 Intel Corporation
+ *
+ * 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.
+ */
+#include "argument.hpp"
+#include <algorithm>
+#include <cassert>
+#include <iostream>
+#include <iterator>
+#include <string>
+
+ArgumentParser::ArgumentParser(int argc, char** argv)
+{
+ auto option = 0;
+
+ while (-1 != (option = getopt_long(argc, argv, optionstr, options, NULL)))
+ {
+ if ((option == '?') || (option == 'h'))
+ {
+ usage(argv);
+ exit(-1);
+ }
+
+ auto i = &options[0];
+ while ((i->val != option) && (i->val != 0))
+ {
+ ++i;
+ }
+
+ if (i->val)
+ {
+ arguments[i->name] = (i->has_arg ? optarg : true_string);
+ }
+ }
+}
+
+const std::string& ArgumentParser::operator[](const std::string& opt)
+{
+ auto i = arguments.find(opt);
+ if (i == arguments.end())
+ {
+ return empty_string;
+ }
+ else
+ {
+ return i->second;
+ }
+}
+
+void ArgumentParser::usage(char** argv)
+{
+ std::cerr << "Usage: " << argv[0] << " [options]\n";
+ std::cerr << "Options:\n";
+ std::cerr << " --help Print this menu\n";
+ std::cerr << " --path=<Dbus Object path> Dbus object path.\n"
+ << " Ex: /org/openbmc/control/power0\n";
+
+ std::cerr
+ << " --service=<Dbus Service name> Dbus Service name.\n"
+ << " Ex: org.openbmc.control.Power\n";
+ std::cerr
+ << " --interface=<Dbus interface name> Dbus interface name.\n"
+ << " Ex: org.openbmc.control.Power\n";
+ std::cerr
+ << " --property=<Dbus property name> Dbus property name.\n"
+ << " Ex: pgood\n";
+
+ std::cerr
+ << " --expect=<expected value> Dbus property value.\n"
+ << " Ex: 1\n";
+
+ std::cerr << std::flush;
+}
+
+const option ArgumentParser::options[] =
+{
+ {"path", required_argument, NULL, 'p'},
+ {"service", required_argument, NULL, 's'},
+ {"interface", required_argument, NULL, 'i'},
+ {"property", required_argument, NULL, 'r'},
+ {"expect", required_argument, NULL, 'e'},
+ {"help", no_argument, NULL, 'h'},
+ {0, 0, 0, 0},
+};
+
+const char* ArgumentParser::optionstr = "p:s:i:r:e:?h";
+
+const std::string ArgumentParser::true_string = "true";
+const std::string ArgumentParser::empty_string = "";
diff --git a/tools/prop_wait/src/prop_wait.cpp b/tools/prop_wait/src/prop_wait.cpp
new file mode 100644
index 0000000..e2e04c7
--- /dev/null
+++ b/tools/prop_wait/src/prop_wait.cpp
@@ -0,0 +1,151 @@
+/**
+ * Copyright (c) 2017 Intel Corporation
+ *
+ * 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.
+ */
+
+// A tool used to wait for a dbus property(int32_t) to be the expected value
+#include <unistd.h>
+#include <phosphor-logging/log.hpp>
+#include <sdbusplus/bus.hpp>
+#include <sdbusplus/bus/match.hpp>
+#include <cstdio>
+#include <cstdlib>
+#include <fstream>
+#include <iostream>
+#include <string>
+#include "argument.hpp"
+
+static bool Waiting = true;
+static auto property = ArgumentParser::empty_string;
+static auto expect_val = ArgumentParser::empty_string;
+
+static int propChanged(sd_bus_message* msg, void* userData,
+ sd_bus_error* retError)
+{
+ std::string iface;
+ std::map<std::string, sdbusplus::message::variant<int32_t>> data;
+
+ auto sdPlusMsg = sdbusplus::message::message(msg);
+
+ sdPlusMsg.read(iface, data);
+
+ auto prop = data.find(property);
+
+ if (prop != data.end())
+ {
+ int32_t prop_val = -1;
+ prop_val = sdbusplus::message::variant_ns::get<int32_t>(prop->second);
+
+ if (prop_val == std::stoi(expect_val))
+ {
+ Waiting = false;
+ }
+ else
+ {
+ Waiting = true;
+ }
+ }
+
+ return 0;
+}
+
+static void ExitWithError(const char* err, char** argv)
+{
+ ArgumentParser::usage(argv);
+ std::cerr << std::endl;
+ std::cerr << "ERROR: " << err << std::endl;
+ exit(-1);
+}
+
+int main(int argc, char* argv[])
+{
+ auto options = ArgumentParser(argc, argv);
+
+ auto path = options["path"];
+ if (path == ArgumentParser::empty_string)
+ {
+ ExitWithError("path not specified", argv);
+ }
+
+ auto service = options["service"];
+ if (service == ArgumentParser::empty_string)
+ {
+ ExitWithError("service not specified", argv);
+ }
+
+ auto interface = options["interface"];
+ if (interface == ArgumentParser::empty_string)
+ {
+ ExitWithError("interface not specified", argv);
+ }
+
+ property = options["property"];
+ if (property == ArgumentParser::empty_string)
+ {
+ ExitWithError("property not specified", argv);
+ }
+
+ expect_val = options["expect"];
+ if (expect_val == ArgumentParser::empty_string)
+ {
+ ExitWithError("expect value not specified", argv);
+ }
+
+ auto bus = sdbusplus::bus::new_default();
+
+ std::string match_str =
+ sdbusplus::bus::match::rules::propertiesChanged(path, interface);
+
+ sdbusplus::message::variant<int32_t> prop_val = -1;
+
+ auto method = bus.new_method_call(std::string(service).c_str(),
+ std::string(path).c_str(),
+ "org.freedesktop.DBus.Properties", "Get");
+
+ method.append(interface, property);
+
+ auto reply = bus.call(method);
+ reply.read(prop_val);
+ if (reply.is_method_error())
+ {
+ phosphor::logging::log<phosphor::logging::level::ERR>(
+ "Error in method call to get property");
+ return -1;
+ }
+
+ if (prop_val == std::stoi(expect_val))
+ {
+ return 0;
+ }
+ else
+ {
+ Waiting = true;
+ }
+
+ // Setup Signal Handler
+ sdbusplus::bus::match::match waitSignals(bus, match_str.c_str(),
+ propChanged, nullptr);
+ // Wait for signal
+ while (Waiting)
+ {
+ bus.process_discard();
+ if (!Waiting)
+ {
+ break;
+ }
+ bus.wait();
+ }
+
+ return 0;
+}