summaryrefslogtreecommitdiff
path: root/services
diff options
context:
space:
mode:
authorYong Li <yong.b.li@intel.com>2017-11-24 15:41:23 +0300
committerYong Li <yong.b.li@linux.intel.com>2018-04-11 06:23:32 +0300
commit49ac43d9cae497fa0755af42bfb33952acbdf445 (patch)
tree864acbaa8d8acda580296cb91eeeb99af2de4a63 /services
parentc8e06e4f91a3673f50b14919dc2c1c9d5acefc40 (diff)
downloadprovingground-49ac43d9cae497fa0755af42bfb33952acbdf445.tar.xz
Implement the power/reset button monitor using sdbusplus
Implement the below service using sdbusplus, as a replacement: https://github.com/openbmc/skeleton/blob/master/pwrbutton/button_power_obj.c https://github.com/openbmc/skeleton/blob/master/rstbutton/button_reset_obj.c Change-Id: Ib8e4dbc6bb062b729cd012f0688b028e695795ec Signed-off-by: Yong Li <yong.b.li@linux.intel.com>
Diffstat (limited to 'services')
-rw-r--r--services/chassis/Buttons/.clang-format85
-rw-r--r--services/chassis/Buttons/CMakeLists.txt119
-rw-r--r--services/chassis/Buttons/inc/Common.hpp9
-rw-r--r--services/chassis/Buttons/inc/PowerButton.hpp97
-rw-r--r--services/chassis/Buttons/inc/ResetButton.hpp96
-rw-r--r--services/chassis/Buttons/src/PowerButton.cpp54
-rw-r--r--services/chassis/Buttons/src/ResetButton.cpp39
-rw-r--r--services/chassis/Buttons/src/main.cpp67
-rw-r--r--services/chassis/Buttons/xyz/openbmc_project/Chassis/Buttons/Power.errors.yaml9
-rw-r--r--services/chassis/Buttons/xyz/openbmc_project/Chassis/Buttons/Power.interface.yaml51
-rw-r--r--services/chassis/Buttons/xyz/openbmc_project/Chassis/Buttons/Reset.errors.yaml9
-rw-r--r--services/chassis/Buttons/xyz/openbmc_project/Chassis/Buttons/Reset.interface.yaml24
-rw-r--r--services/chassis/CMakeLists.txt8
-rw-r--r--services/chassis/Gpio/.clang-format85
-rw-r--r--services/chassis/Gpio/CMakeLists.txt14
-rw-r--r--services/chassis/Gpio/inc/Gpio.hpp3
-rw-r--r--services/chassis/Gpio/src/Gpio.cpp182
17 files changed, 951 insertions, 0 deletions
diff --git a/services/chassis/Buttons/.clang-format b/services/chassis/Buttons/.clang-format
new file mode 100644
index 0000000..bbc1bb1
--- /dev/null
+++ b/services/chassis/Buttons/.clang-format
@@ -0,0 +1,85 @@
+---
+Language: Cpp
+# BasedOnStyle: LLVM
+AccessModifierOffset: -2
+AlignAfterOpenBracket: Align
+AlignConsecutiveAssignments: false
+AlignConsecutiveDeclarations: false
+AlignEscapedNewlinesLeft: false
+AlignOperands: true
+AlignTrailingComments: true
+AllowAllParametersOfDeclarationOnNextLine: true
+AllowShortBlocksOnASingleLine: false
+AllowShortCaseLabelsOnASingleLine: false
+AllowShortFunctionsOnASingleLine: None
+AllowShortIfStatementsOnASingleLine: false
+AllowShortLoopsOnASingleLine: false
+AlwaysBreakAfterDefinitionReturnType: None
+AlwaysBreakAfterReturnType: None
+AlwaysBreakBeforeMultilineStrings: false
+AlwaysBreakTemplateDeclarations: false
+BinPackArguments: true
+BinPackParameters: true
+BraceWrapping:
+ AfterClass: true
+ AfterControlStatement: true
+ AfterEnum: true
+ AfterFunction: true
+ AfterNamespace: true
+ AfterObjCDeclaration: true
+ AfterStruct: true
+ AfterUnion: true
+ BeforeCatch: true
+ BeforeElse: true
+ IndentBraces: false
+BreakBeforeBinaryOperators: None
+BreakBeforeBraces: Custom
+BreakBeforeTernaryOperators: true
+BreakConstructorInitializers: AfterColon
+ColumnLimit: 80
+CommentPragmas: '^ IWYU pragma:'
+ConstructorInitializerAllOnOneLineOrOnePerLine: false
+ConstructorInitializerIndentWidth: 4
+ContinuationIndentWidth: 4
+Cpp11BracedListStyle: true
+DerivePointerAlignment: true
+PointerAlignment: Left
+DisableFormat: false
+ExperimentalAutoDetectBinPacking: false
+FixNamespaceComments: true
+ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
+IndentCaseLabels: true
+IndentWidth: 4
+IndentWrappedFunctionNames: true
+KeepEmptyLinesAtTheStartOfBlocks: true
+MacroBlockBegin: ''
+MacroBlockEnd: ''
+MaxEmptyLinesToKeep: 1
+NamespaceIndentation: None
+ObjCBlockIndentWidth: 2
+ObjCSpaceAfterProperty: false
+ObjCSpaceBeforeProtocolList: true
+PenaltyBreakBeforeFirstCallParameter: 19
+PenaltyBreakComment: 300
+PenaltyBreakFirstLessLess: 120
+PenaltyBreakString: 1000
+PenaltyExcessCharacter: 1000000
+PenaltyReturnTypeOnItsOwnLine: 60
+PointerAlignment: Right
+ReflowComments: true
+SortIncludes: false
+SpaceAfterCStyleCast: false
+SpaceBeforeAssignmentOperators: true
+SpaceBeforeParens: ControlStatements
+SpaceInEmptyParentheses: false
+SpacesBeforeTrailingComments: 1
+SpacesInAngles: false
+SpacesInContainerLiterals: true
+SpacesInCStyleCastParentheses: false
+SpacesInParentheses: false
+SpacesInSquareBrackets: false
+Standard: Cpp11
+TabWidth: 4
+UseTab: Never
+...
+
diff --git a/services/chassis/Buttons/CMakeLists.txt b/services/chassis/Buttons/CMakeLists.txt
new file mode 100644
index 0000000..8ce6728
--- /dev/null
+++ b/services/chassis/Buttons/CMakeLists.txt
@@ -0,0 +1,119 @@
+cmake_minimum_required(VERSION 2.8.10 FATAL_ERROR)
+project(Buttons CXX)
+set(CMAKE_CXX_STANDARD 14)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+
+set(CMAKE_INSTALL_RPATH ${CMAKE_INSTALL_RPATH} ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR})
+set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
+
+include(GNUInstallDirs)
+
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/inc)
+include_directories(${CMAKE_CURRENT_BINARY_DIR})
+
+set(POWER_DBUS_OBJECT_NAME "xyz/openbmc_project/Chassis/Buttons/Power")
+set(POWER_DBUS_INTF_NAME "xyz.openbmc_project.Chassis.Buttons.Power")
+
+set(RESET_DBUS_OBJECT_NAME "xyz/openbmc_project/Chassis/Buttons/Reset")
+set(RESET_DBUS_INTF_NAME "xyz.openbmc_project.Chassis.Buttons.Reset")
+
+add_definitions(-DPOWER_DBUS_OBJECT_NAME="/${POWER_DBUS_OBJECT_NAME}")
+
+add_definitions(-DRESET_DBUS_OBJECT_NAME="/${RESET_DBUS_OBJECT_NAME}")
+
+set(SRC_FILES
+ src/PowerButton.cpp
+ src/ResetButton.cpp
+ src/main.cpp
+)
+set(GENERATED_SRC_FILES
+ ${POWER_DBUS_OBJECT_NAME}/error.cpp
+ ${POWER_DBUS_OBJECT_NAME}/server.cpp
+ ${RESET_DBUS_OBJECT_NAME}/error.cpp
+ ${RESET_DBUS_OBJECT_NAME}/server.cpp
+)
+
+# import libsystemd
+find_package(PkgConfig REQUIRED)
+pkg_check_modules(SYSTEMD libsystemd REQUIRED)
+include_directories(${SYSTEMD_INCLUDE_DIRS})
+link_directories(${SYSTEMD_LIBRARY_DIRS})
+
+# import sdbusplus
+find_package(PkgConfig REQUIRED)
+pkg_check_modules(SDBUSPLUSPLUS sdbusplus REQUIRED)
+include_directories(${SDBUSPLUSPLUS_INCLUDE_DIRS})
+link_directories(${SDBUSPLUSPLUS_LIBRARY_DIRS})
+find_program(SDBUSPLUSPLUS sdbus++)
+
+# import phosphor-logging
+find_package(PkgConfig REQUIRED)
+pkg_check_modules(LOGGING phosphor-logging REQUIRED)
+include_directories(${LOGGING_INCLUDE_DIRS})
+link_directories(${LOGGING_LIBRARY_DIRS})
+
+# phosphor-dbus-interfaces
+find_package(PkgConfig REQUIRED)
+pkg_check_modules(DBUSINTERFACE phosphor-dbus-interfaces REQUIRED)
+include_directories(${DBUSINTERFACE_INCLUDE_DIRS})
+link_directories(${DBUSINTERFACE_LIBRARY_DIRS})
+
+#include_directories(${CMAKE_CURRENT_BINARY_DIR}/${DBUS_OBJECT_NAME})
+
+add_custom_command(
+ OUTPUT ${POWER_DBUS_OBJECT_NAME}/error.hpp
+ OUTPUT ${POWER_DBUS_OBJECT_NAME}/error.cpp
+ COMMAND mkdir -p ${POWER_DBUS_OBJECT_NAME}
+ COMMAND ${SDBUSPLUSPLUS} -r ${CMAKE_CURRENT_SOURCE_DIR} error exception-header ${POWER_DBUS_INTF_NAME} > ${POWER_DBUS_OBJECT_NAME}/error.hpp
+ COMMAND ${SDBUSPLUSPLUS} -r ${CMAKE_CURRENT_SOURCE_DIR} error exception-cpp ${POWER_DBUS_INTF_NAME} > ${POWER_DBUS_OBJECT_NAME}/error.cpp
+ DEPENDS ${POWER_DBUS_OBJECT_NAME}.errors.yaml
+)
+set_source_files_properties(
+ ${POWER_DBUS_OBJECT_NAME}/error.hpp
+ ${POWER_DBUS_OBJECT_NAME}/error.cpp
+ PROPERTIES GENERATED TRUE)
+
+add_custom_command(
+ OUTPUT ${RESET_DBUS_OBJECT_NAME}/error.hpp
+ OUTPUT ${RESET_DBUS_OBJECT_NAME}/error.cpp
+ COMMAND mkdir -p ${RESET_DBUS_OBJECT_NAME}
+ COMMAND ${SDBUSPLUSPLUS} -r ${CMAKE_CURRENT_SOURCE_DIR} error exception-header ${RESET_DBUS_INTF_NAME} > ${RESET_DBUS_OBJECT_NAME}/error.hpp
+ COMMAND ${SDBUSPLUSPLUS} -r ${CMAKE_CURRENT_SOURCE_DIR} error exception-cpp ${RESET_DBUS_INTF_NAME} > ${RESET_DBUS_OBJECT_NAME}/error.cpp
+ DEPENDS ${RESET_DBUS_OBJECT_NAME}.errors.yaml
+)
+set_source_files_properties(
+ ${RESET_DBUS_OBJECT_NAME}/error.hpp
+ ${RESET_DBUS_OBJECT_NAME}/error.cpp
+ PROPERTIES GENERATED TRUE)
+
+add_custom_command(
+ OUTPUT ${POWER_DBUS_OBJECT_NAME}/server.hpp
+ OUTPUT ${POWER_DBUS_OBJECT_NAME}/server.cpp
+ COMMAND mkdir -p ${POWER_DBUS_OBJECT_NAME}
+ COMMAND ${SDBUSPLUSPLUS} -r ${CMAKE_CURRENT_SOURCE_DIR} interface server-header ${POWER_DBUS_INTF_NAME} > ${POWER_DBUS_OBJECT_NAME}/server.hpp
+ COMMAND ${SDBUSPLUSPLUS} -r ${CMAKE_CURRENT_SOURCE_DIR} interface server-cpp ${POWER_DBUS_INTF_NAME} > ${POWER_DBUS_OBJECT_NAME}/server.cpp
+ DEPENDS ${POWER_DBUS_OBJECT_NAME}.interface.yaml
+)
+set_source_files_properties(
+ ${POWER_DBUS_OBJECT_NAME}/server.hpp
+ ${POWER_DBUS_OBJECT_NAME}/server.cpp
+ PROPERTIES GENERATED TRUE)
+
+add_custom_command(
+ OUTPUT ${RESET_DBUS_OBJECT_NAME}/server.hpp
+ OUTPUT ${RESET_DBUS_OBJECT_NAME}/server.cpp
+ COMMAND mkdir -p ${RESET_DBUS_OBJECT_NAME}
+ COMMAND ${SDBUSPLUSPLUS} -r ${CMAKE_CURRENT_SOURCE_DIR} interface server-header ${RESET_DBUS_INTF_NAME} > ${RESET_DBUS_OBJECT_NAME}/server.hpp
+ COMMAND ${SDBUSPLUSPLUS} -r ${CMAKE_CURRENT_SOURCE_DIR} interface server-cpp ${RESET_DBUS_INTF_NAME} > ${RESET_DBUS_OBJECT_NAME}/server.cpp
+ DEPENDS ${RESET_DBUS_OBJECT_NAME}.interface.yaml
+)
+set_source_files_properties(
+ ${RESET_DBUS_OBJECT_NAME}/server.hpp
+ ${RESET_DBUS_OBJECT_NAME}/server.cpp
+ PROPERTIES GENERATED TRUE)
+
+add_executable(${PROJECT_NAME} ${SRC_FILES} ${GENERATED_SRC_FILES})
+target_link_libraries(${PROJECT_NAME} ${SYSTEMD_LIBRARIES} gpio)
+target_link_libraries(${PROJECT_NAME} "${SDBUSPLUSPLUS_LIBRARIES} -lstdc++fs")
+
+install (TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR})
diff --git a/services/chassis/Buttons/inc/Common.hpp b/services/chassis/Buttons/inc/Common.hpp
new file mode 100644
index 0000000..b7651ec
--- /dev/null
+++ b/services/chassis/Buttons/inc/Common.hpp
@@ -0,0 +1,9 @@
+#pragma once
+struct EventDeleter
+{
+ void operator()(sd_event *event) const
+ {
+ event = sd_event_unref(event);
+ }
+};
+using EventPtr = std::unique_ptr<sd_event, EventDeleter>; \ No newline at end of file
diff --git a/services/chassis/Buttons/inc/PowerButton.hpp b/services/chassis/Buttons/inc/PowerButton.hpp
new file mode 100644
index 0000000..6ec947e
--- /dev/null
+++ b/services/chassis/Buttons/inc/PowerButton.hpp
@@ -0,0 +1,97 @@
+#pragma once
+#include "xyz/openbmc_project/Chassis/Buttons/Power/error.hpp"
+#include "xyz/openbmc_project/Chassis/Buttons/Power/server.hpp"
+#include "Common.hpp"
+#include "Gpio.hpp"
+
+const static constexpr char *POWER_BUTTON = "POWER_BUTTON";
+
+struct PowerButton
+ : sdbusplus::server::object::object<
+ sdbusplus::xyz::openbmc_project::Chassis::Buttons::server::Power>
+{
+
+ PowerButton(sdbusplus::bus::bus &bus, const char *path, EventPtr &event,
+ sd_event_io_handler_t handler = PowerButton::EventHandler) :
+ sdbusplus::server::object::object<
+ sdbusplus::xyz::openbmc_project::Chassis::Buttons::server::Power>(
+ bus, path),
+ fd(-1), bus(bus), event(event), callbackHandler(handler)
+ {
+
+ int ret;
+
+ // config gpio
+ ret = ::configGpio(POWER_BUTTON, &fd, bus);
+ if (ret < 0)
+ {
+ throw std::runtime_error("failed to config GPIO");
+ }
+
+ ret = sd_event_add_io(event.get(), nullptr, fd, EPOLLPRI,
+ callbackHandler, this);
+ if (ret < 0)
+ {
+ throw std::runtime_error("failed to add to event loop");
+ }
+ }
+
+ ~PowerButton()
+ {
+ ::closeGpio(fd);
+ }
+ bool simPress() override;
+ bool simLongPress() override;
+ static int EventHandler(sd_event_source *es, int fd, uint32_t revents,
+ void *userdata)
+ {
+
+ int n;
+ char buf;
+
+ PowerButton *powerButton = static_cast<PowerButton *>(userdata);
+
+ if (!powerButton)
+ {
+ phosphor::logging::log<phosphor::logging::level::ERR>(
+ "null pointer!");
+ return -1;
+ }
+
+ n = ::lseek(fd, 0, SEEK_SET);
+
+ if (n < 0)
+ {
+ phosphor::logging::log<phosphor::logging::level::ERR>(
+ "lseek error!");
+ return n;
+ }
+
+ n = ::read(fd, &buf, 1);
+ if (n < 0)
+ {
+ phosphor::logging::log<phosphor::logging::level::ERR>(
+ "read error!");
+ return n;
+ }
+
+ if (buf == '0')
+ {
+ // emit pressed signal
+ powerButton->pressed();
+ }
+ else
+ {
+ // released
+ powerButton->released();
+ }
+
+ return 0;
+ }
+
+ private:
+ int fd;
+ sdbusplus::bus::bus &bus;
+ EventPtr &event;
+ sd_event_io_handler_t callbackHandler;
+};
diff --git a/services/chassis/Buttons/inc/ResetButton.hpp b/services/chassis/Buttons/inc/ResetButton.hpp
new file mode 100644
index 0000000..f5f1aa7
--- /dev/null
+++ b/services/chassis/Buttons/inc/ResetButton.hpp
@@ -0,0 +1,96 @@
+#pragma once
+#include "xyz/openbmc_project/Chassis/Buttons/Reset/error.hpp"
+#include "xyz/openbmc_project/Chassis/Buttons/Reset/server.hpp"
+#include "Common.hpp"
+#include "Gpio.hpp"
+
+const static constexpr char *RESET_BUTTON = "RESET_BUTTON";
+
+struct ResetButton
+ : sdbusplus::server::object::object<
+ sdbusplus::xyz::openbmc_project::Chassis::Buttons::server::Reset>
+{
+
+ ResetButton(sdbusplus::bus::bus &bus, const char *path, EventPtr &event,
+ sd_event_io_handler_t handler = ResetButton::EventHandler) :
+ sdbusplus::server::object::object<
+ sdbusplus::xyz::openbmc_project::Chassis::Buttons::server::Reset>(
+ bus, path),
+ fd(-1), bus(bus), event(event), callbackHandler(handler)
+ {
+
+ int ret;
+
+ // config gpio
+ ret = ::configGpio(RESET_BUTTON, &fd, bus);
+ if (ret < 0)
+ {
+ throw std::runtime_error("failed to config GPIO");
+ }
+
+ ret = sd_event_add_io(event.get(), nullptr, fd, EPOLLPRI,
+ callbackHandler, this);
+ if (ret < 0)
+ {
+ throw std::runtime_error("failed to add to event loop");
+ }
+ }
+
+ ~ResetButton()
+ {
+ ::closeGpio(fd);
+ }
+ bool simPress() override;
+ static int EventHandler(sd_event_source *es, int fd, uint32_t revents,
+ void *userdata)
+ {
+
+ int n;
+ char buf;
+
+ ResetButton *resetButton = static_cast<ResetButton *>(userdata);
+
+ if (!resetButton)
+ {
+ phosphor::logging::log<phosphor::logging::level::ERR>(
+ "null pointer!");
+ return -1;
+ }
+
+ n = ::lseek(fd, 0, SEEK_SET);
+
+ if (n < 0)
+ {
+ phosphor::logging::log<phosphor::logging::level::ERR>(
+ "lseek error!");
+ return n;
+ }
+
+ n = ::read(fd, &buf, 1);
+ if (n < 0)
+ {
+ phosphor::logging::log<phosphor::logging::level::ERR>(
+ "read error!");
+ return n;
+ }
+
+ if (buf == '0')
+ {
+ // emit pressed signal
+ resetButton->pressed();
+ }
+ else
+ {
+ // released
+ resetButton->released();
+ }
+
+ return 0;
+ }
+
+ private:
+ int fd;
+ sdbusplus::bus::bus &bus;
+ EventPtr &event;
+ sd_event_io_handler_t callbackHandler;
+};
diff --git a/services/chassis/Buttons/src/PowerButton.cpp b/services/chassis/Buttons/src/PowerButton.cpp
new file mode 100644
index 0000000..79f9f83
--- /dev/null
+++ b/services/chassis/Buttons/src/PowerButton.cpp
@@ -0,0 +1,54 @@
+/*
+// Copyright (c) 2018 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 <chrono>
+#include <experimental/filesystem>
+#include <fcntl.h>
+#include <fstream>
+#include <iostream>
+#include <phosphor-logging/elog-errors.hpp>
+#include <phosphor-logging/elog.hpp>
+#include <phosphor-logging/log.hpp>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <systemd/sd-event.h>
+#include <unistd.h>
+#include <xyz/openbmc_project/Common/error.hpp>
+#include "PowerButton.hpp"
+
+const static constexpr char *SYSMGR_SERVICE = "org.openbmc.managers.System";
+const static constexpr char *SYSMGR_OBJ_PATH = "/org/openbmc/managers/System";
+const static constexpr char *SYSMGR_INTERFACE = "org.openbmc.managers.System";
+
+static constexpr size_t LONG_PRESS_MS = 6000;
+
+bool PowerButton::simPress()
+{
+ uint64_t currentTimeMs =
+ std::chrono::duration_cast<std::chrono::milliseconds>(
+ std::chrono::steady_clock::now().time_since_epoch())
+ .count();
+ pressedTime(currentTimeMs);
+ buttonState(false);
+ pressed();
+ return true;
+}
+
+bool PowerButton::simLongPress()
+{
+ buttonState(true);
+ pressedLong();
+ return true;
+} \ No newline at end of file
diff --git a/services/chassis/Buttons/src/ResetButton.cpp b/services/chassis/Buttons/src/ResetButton.cpp
new file mode 100644
index 0000000..d299fee
--- /dev/null
+++ b/services/chassis/Buttons/src/ResetButton.cpp
@@ -0,0 +1,39 @@
+/*
+// Copyright (c) 2018 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 <chrono>
+#include <experimental/filesystem>
+#include <fcntl.h>
+#include <fstream>
+#include <iostream>
+#include <phosphor-logging/elog-errors.hpp>
+#include <phosphor-logging/elog.hpp>
+#include <phosphor-logging/log.hpp>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <systemd/sd-event.h>
+#include <unistd.h>
+#include <xyz/openbmc_project/Common/error.hpp>
+#include "ResetButton.hpp"
+
+const static constexpr char *SYSMGR_SERVICE = "org.openbmc.managers.System";
+const static constexpr char *SYSMGR_OBJ_PATH = "/org/openbmc/managers/System";
+const static constexpr char *SYSMGR_INTERFACE = "org.openbmc.managers.System";
+
+bool ResetButton::simPress()
+{
+ pressed();
+ return true;
+} \ No newline at end of file
diff --git a/services/chassis/Buttons/src/main.cpp b/services/chassis/Buttons/src/main.cpp
new file mode 100644
index 0000000..a329dab
--- /dev/null
+++ b/services/chassis/Buttons/src/main.cpp
@@ -0,0 +1,67 @@
+#include <chrono>
+#include <experimental/filesystem>
+#include <fcntl.h>
+#include <fstream>
+#include <iostream>
+#include <phosphor-logging/elog-errors.hpp>
+#include <phosphor-logging/elog.hpp>
+#include <phosphor-logging/log.hpp>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <systemd/sd-event.h>
+#include <unistd.h>
+#include <xyz/openbmc_project/Common/error.hpp>
+#include "ResetButton.hpp"
+#include "PowerButton.hpp"
+
+int main(int argc, char *argv[])
+{
+ int ret = 0;
+
+ phosphor::logging::log<phosphor::logging::level::INFO>(
+ "Start power button service...");
+
+ sd_event *event = nullptr;
+ ret = sd_event_default(&event);
+ if (ret < 0)
+ {
+ phosphor::logging::log<phosphor::logging::level::ERR>(
+ "Error creating a default sd_event handler");
+ return ret;
+ }
+ EventPtr eventP{event};
+ event = nullptr;
+
+ auto bus = sdbusplus::bus::new_default();
+ sdbusplus::server::manager::manager objManager{
+ bus, "/xyz/openbmc_project/Chassis/Buttons"};
+
+ bus.request_name("xyz.openbmc_project.Chassis.Buttons");
+
+ PowerButton powerButton{bus, POWER_DBUS_OBJECT_NAME, eventP};
+
+ ResetButton resetButton{bus, RESET_DBUS_OBJECT_NAME, eventP};
+
+ try
+ {
+ bus.attach_event(eventP.get(), SD_EVENT_PRIORITY_NORMAL);
+
+ while (true)
+ {
+ ret = sd_event_run(eventP.get(), (uint64_t)-1);
+ if (ret < 0)
+ {
+ phosphor::logging::log<phosphor::logging::level::ERR>(
+ "Error waiting for events");
+ break;
+ }
+ }
+ }
+
+ catch (std::exception &e)
+ {
+ phosphor::logging::log<phosphor::logging::level::ERR>(e.what());
+ ret = -1;
+ }
+ return ret;
+}
diff --git a/services/chassis/Buttons/xyz/openbmc_project/Chassis/Buttons/Power.errors.yaml b/services/chassis/Buttons/xyz/openbmc_project/Chassis/Buttons/Power.errors.yaml
new file mode 100644
index 0000000..9de4b9d
--- /dev/null
+++ b/services/chassis/Buttons/xyz/openbmc_project/Chassis/Buttons/Power.errors.yaml
@@ -0,0 +1,9 @@
+- name: UnsupportedCommand
+ description: >
+ An unsupported command was attempted.
+- name: InvalidParameter
+ description: >
+ An invalid parameter was attempted.
+- name: IOError
+ description: >
+ An IO error occurred.
diff --git a/services/chassis/Buttons/xyz/openbmc_project/Chassis/Buttons/Power.interface.yaml b/services/chassis/Buttons/xyz/openbmc_project/Chassis/Buttons/Power.interface.yaml
new file mode 100644
index 0000000..e361ce7
--- /dev/null
+++ b/services/chassis/Buttons/xyz/openbmc_project/Chassis/Buttons/Power.interface.yaml
@@ -0,0 +1,51 @@
+description: >
+ power button control service
+methods:
+ - name: simPress
+ description: >
+ emulate power button press.
+ returns:
+ - name: state
+ type: boolean
+ description: >
+ The result of command.
+ errors:
+ - self.Error.UnsupportedCommand
+ - self.Error.InvalidParameter
+ - self.Error.IOError
+
+ - name: simLongPress
+ description: >
+ emulate power button long press.
+ returns:
+ - name: state
+ type: boolean
+ description: >
+ The result of command.
+ errors:
+ - self.Error.UnsupportedCommand
+ - self.Error.InvalidParameter
+ - self.Error.IOError
+
+properties:
+ - name: ButtonState
+ type: boolean
+ default: 0
+ description: >
+ power button value
+
+ - name: PressedTime
+ type: uint64
+ default: 0
+ description: >
+ when power button is pressed
+signals:
+ - name: Released
+ description: >
+ power button release signal
+ - name: Pressed
+ description: >
+ power button pressed signal
+ - name: PressedLong
+ description: >
+ power button long pressed signal
diff --git a/services/chassis/Buttons/xyz/openbmc_project/Chassis/Buttons/Reset.errors.yaml b/services/chassis/Buttons/xyz/openbmc_project/Chassis/Buttons/Reset.errors.yaml
new file mode 100644
index 0000000..9de4b9d
--- /dev/null
+++ b/services/chassis/Buttons/xyz/openbmc_project/Chassis/Buttons/Reset.errors.yaml
@@ -0,0 +1,9 @@
+- name: UnsupportedCommand
+ description: >
+ An unsupported command was attempted.
+- name: InvalidParameter
+ description: >
+ An invalid parameter was attempted.
+- name: IOError
+ description: >
+ An IO error occurred.
diff --git a/services/chassis/Buttons/xyz/openbmc_project/Chassis/Buttons/Reset.interface.yaml b/services/chassis/Buttons/xyz/openbmc_project/Chassis/Buttons/Reset.interface.yaml
new file mode 100644
index 0000000..700583f
--- /dev/null
+++ b/services/chassis/Buttons/xyz/openbmc_project/Chassis/Buttons/Reset.interface.yaml
@@ -0,0 +1,24 @@
+description: >
+ reset button control service
+methods:
+ - name: simPress
+ description: >
+ emulate reset button press.
+ returns:
+ - name: state
+ type: boolean
+ description: >
+ The result of command.
+ errors:
+ - self.Error.UnsupportedCommand
+ - self.Error.InvalidParameter
+ - self.Error.IOError
+
+
+signals:
+ - name: Released
+ description: >
+ reset button release signal
+ - name: Pressed
+ description: >
+ reset button pressed signal
diff --git a/services/chassis/CMakeLists.txt b/services/chassis/CMakeLists.txt
new file mode 100644
index 0000000..6404467
--- /dev/null
+++ b/services/chassis/CMakeLists.txt
@@ -0,0 +1,8 @@
+cmake_minimum_required(VERSION 2.8.10 FATAL_ERROR)
+set(CMAKE_CXX_STANDARD 14)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/Gpio/inc)
+
+add_subdirectory(Gpio)
+add_subdirectory(Buttons) \ No newline at end of file
diff --git a/services/chassis/Gpio/.clang-format b/services/chassis/Gpio/.clang-format
new file mode 100644
index 0000000..bbc1bb1
--- /dev/null
+++ b/services/chassis/Gpio/.clang-format
@@ -0,0 +1,85 @@
+---
+Language: Cpp
+# BasedOnStyle: LLVM
+AccessModifierOffset: -2
+AlignAfterOpenBracket: Align
+AlignConsecutiveAssignments: false
+AlignConsecutiveDeclarations: false
+AlignEscapedNewlinesLeft: false
+AlignOperands: true
+AlignTrailingComments: true
+AllowAllParametersOfDeclarationOnNextLine: true
+AllowShortBlocksOnASingleLine: false
+AllowShortCaseLabelsOnASingleLine: false
+AllowShortFunctionsOnASingleLine: None
+AllowShortIfStatementsOnASingleLine: false
+AllowShortLoopsOnASingleLine: false
+AlwaysBreakAfterDefinitionReturnType: None
+AlwaysBreakAfterReturnType: None
+AlwaysBreakBeforeMultilineStrings: false
+AlwaysBreakTemplateDeclarations: false
+BinPackArguments: true
+BinPackParameters: true
+BraceWrapping:
+ AfterClass: true
+ AfterControlStatement: true
+ AfterEnum: true
+ AfterFunction: true
+ AfterNamespace: true
+ AfterObjCDeclaration: true
+ AfterStruct: true
+ AfterUnion: true
+ BeforeCatch: true
+ BeforeElse: true
+ IndentBraces: false
+BreakBeforeBinaryOperators: None
+BreakBeforeBraces: Custom
+BreakBeforeTernaryOperators: true
+BreakConstructorInitializers: AfterColon
+ColumnLimit: 80
+CommentPragmas: '^ IWYU pragma:'
+ConstructorInitializerAllOnOneLineOrOnePerLine: false
+ConstructorInitializerIndentWidth: 4
+ContinuationIndentWidth: 4
+Cpp11BracedListStyle: true
+DerivePointerAlignment: true
+PointerAlignment: Left
+DisableFormat: false
+ExperimentalAutoDetectBinPacking: false
+FixNamespaceComments: true
+ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
+IndentCaseLabels: true
+IndentWidth: 4
+IndentWrappedFunctionNames: true
+KeepEmptyLinesAtTheStartOfBlocks: true
+MacroBlockBegin: ''
+MacroBlockEnd: ''
+MaxEmptyLinesToKeep: 1
+NamespaceIndentation: None
+ObjCBlockIndentWidth: 2
+ObjCSpaceAfterProperty: false
+ObjCSpaceBeforeProtocolList: true
+PenaltyBreakBeforeFirstCallParameter: 19
+PenaltyBreakComment: 300
+PenaltyBreakFirstLessLess: 120
+PenaltyBreakString: 1000
+PenaltyExcessCharacter: 1000000
+PenaltyReturnTypeOnItsOwnLine: 60
+PointerAlignment: Right
+ReflowComments: true
+SortIncludes: false
+SpaceAfterCStyleCast: false
+SpaceBeforeAssignmentOperators: true
+SpaceBeforeParens: ControlStatements
+SpaceInEmptyParentheses: false
+SpacesBeforeTrailingComments: 1
+SpacesInAngles: false
+SpacesInContainerLiterals: true
+SpacesInCStyleCastParentheses: false
+SpacesInParentheses: false
+SpacesInSquareBrackets: false
+Standard: Cpp11
+TabWidth: 4
+UseTab: Never
+...
+
diff --git a/services/chassis/Gpio/CMakeLists.txt b/services/chassis/Gpio/CMakeLists.txt
new file mode 100644
index 0000000..5f4b0e1
--- /dev/null
+++ b/services/chassis/Gpio/CMakeLists.txt
@@ -0,0 +1,14 @@
+cmake_minimum_required(VERSION 2.8.10 FATAL_ERROR)
+project(gpio CXX)
+set(CMAKE_CXX_STANDARD 14)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+
+include(GNUInstallDirs)
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/inc)
+
+add_library(${PROJECT_NAME} SHARED src/Gpio.cpp)
+
+set_target_properties(${PROJECT_NAME} PROPERTIES VERSION "0.1.0")
+set_target_properties(${PROJECT_NAME} PROPERTIES SOVERSION "0")
+
+install (TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_LIBDIR})
diff --git a/services/chassis/Gpio/inc/Gpio.hpp b/services/chassis/Gpio/inc/Gpio.hpp
new file mode 100644
index 0000000..c906976
--- /dev/null
+++ b/services/chassis/Gpio/inc/Gpio.hpp
@@ -0,0 +1,3 @@
+#pragma once
+int configGpio(const char *gpioName, int *fd, sdbusplus::bus::bus &bus);
+int closeGpio(int fd); \ No newline at end of file
diff --git a/services/chassis/Gpio/src/Gpio.cpp b/services/chassis/Gpio/src/Gpio.cpp
new file mode 100644
index 0000000..ef1490c
--- /dev/null
+++ b/services/chassis/Gpio/src/Gpio.cpp
@@ -0,0 +1,182 @@
+#include <experimental/filesystem>
+#include <fcntl.h>
+#include <fstream>
+#include <iostream>
+#include <phosphor-logging/elog-errors.hpp>
+#include <phosphor-logging/elog.hpp>
+#include <phosphor-logging/log.hpp>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <systemd/sd-event.h>
+#include <unistd.h>
+#include <xyz/openbmc_project/Common/error.hpp>
+#include "Gpio.hpp"
+
+const static constexpr char *SYSMGR_SERVICE = "org.openbmc.managers.System";
+const static constexpr char *SYSMGR_OBJ_PATH = "/org/openbmc/managers/System";
+const static constexpr char *SYSMGR_INTERFACE = "org.openbmc.managers.System";
+
+int closeGpio(int fd)
+{
+ if (fd > 0)
+ {
+ ::close(fd);
+ }
+ return 0;
+}
+
+int configGpio(const char *gpioName, int *fd, sdbusplus::bus::bus &bus)
+{
+ auto method = bus.new_method_call(SYSMGR_SERVICE, SYSMGR_OBJ_PATH,
+ SYSMGR_INTERFACE, "gpioInit");
+
+ method.append(gpioName);
+
+ auto result = bus.call(method);
+
+ if (result.is_method_error())
+ {
+ phosphor::logging::log<phosphor::logging::level::ERR>(
+ "bus call error!");
+ return -1;
+ }
+
+ int32_t gpioNum;
+ std::string gpioDev;
+ std::string gpioDirection;
+
+ result.read(gpioDev, gpioNum, gpioDirection);
+
+ std::string devPath;
+
+ std::fstream stream;
+
+ stream.exceptions(std::ifstream::failbit | std::ifstream::badbit);
+
+ devPath.clear();
+ devPath = gpioDev + "/gpio" + std::to_string(gpioNum) + "/value";
+
+ std::experimental::filesystem::path fullPath(devPath);
+
+ if (std::experimental::filesystem::exists(fullPath))
+ {
+ phosphor::logging::log<phosphor::logging::level::INFO>("GPIO exported");
+ }
+ else
+ {
+ devPath.clear();
+ devPath = gpioDev + "/export";
+
+ stream.open(devPath, std::fstream::out);
+ try
+ {
+ stream << gpioNum;
+ stream.close();
+ }
+
+ catch (const std::exception &e)
+ {
+ phosphor::logging::log<phosphor::logging::level::ERR>(
+ "Error in writing!",
+ phosphor::logging::entry("PATH=%s", devPath.c_str()),
+ phosphor::logging::entry("NUM=%d", gpioNum));
+ return -1;
+ }
+ }
+
+ if (gpioDirection == "out")
+ {
+ devPath.clear();
+ devPath = gpioDev + "/gpio" + std::to_string(gpioNum) + "/value";
+
+ uint32_t currentValue;
+
+ stream.open(devPath, std::fstream::in);
+ try
+ {
+ stream >> currentValue;
+ stream.close();
+ }
+
+ catch (const std::exception &e)
+ {
+ phosphor::logging::log<phosphor::logging::level::ERR>(
+ "Error in reading!",
+ phosphor::logging::entry("PATH=%s", devPath.c_str()));
+ return -1;
+ }
+
+ const char *direction = currentValue ? "high" : "low";
+
+ devPath.clear();
+ devPath = gpioDev + "/gpio" + std::to_string(gpioNum) + "/direction";
+
+ stream.open(devPath, std::fstream::out);
+ try
+ {
+ stream << direction;
+ stream.close();
+ }
+
+ catch (const std::exception &e)
+ {
+ phosphor::logging::log<phosphor::logging::level::ERR>(
+ "Error in writing!");
+ return -1;
+ }
+ }
+ else if (gpioDirection == "in")
+ {
+ devPath.clear();
+ devPath = gpioDev + "/gpio" + std::to_string(gpioNum) + "/direction";
+
+ stream.open(devPath, std::fstream::out);
+ try
+ {
+ stream << gpioDirection;
+ stream.close();
+ }
+
+ catch (const std::exception &e)
+ {
+ phosphor::logging::log<phosphor::logging::level::ERR>(
+ "Error in writing!");
+ return -1;
+ }
+ }
+ else if ((gpioDirection == "both"))
+ {
+
+ // For gpio configured as ‘both’, it is an interrupt pin and trigged on
+ // both rising and falling signals
+ devPath.clear();
+ devPath = gpioDev + "/gpio" + std::to_string(gpioNum) + "/edge";
+
+ stream.open(devPath, std::fstream::out);
+ try
+ {
+ stream << gpioDirection;
+ stream.close();
+ }
+
+ catch (const std::exception &e)
+ {
+ phosphor::logging::log<phosphor::logging::level::ERR>(
+ "Error in writing!");
+ return -1;
+ }
+ }
+
+ devPath.clear();
+ devPath = gpioDev + "/gpio" + std::to_string(gpioNum) + "/value";
+
+ *fd = ::open(devPath.c_str(), O_RDWR | O_NONBLOCK);
+
+ if (*fd < 0)
+ {
+ phosphor::logging::log<phosphor::logging::level::ERR>("open error!");
+ return -1;
+ }
+
+ return 0;
+}