diff options
author | Tom Joseph <tomjoseph@in.ibm.com> | 2018-03-23 17:55:40 +0530 |
---|---|---|
committer | Vernon Mauery <vernon.mauery@linux.intel.com> | 2018-04-04 15:21:30 +0000 |
commit | 5110c1252fa881bd90f516357ca6c31cb88d9342 (patch) | |
tree | e0d3b2a161226bb5e221b5c4ccd2bbe272d0a6d5 | |
parent | e47fdfb5d79a32075ec10f5549c07a2e8310079f (diff) | |
download | phosphor-host-ipmid-5110c1252fa881bd90f516357ca6c31cb88d9342.tar.gz phosphor-host-ipmid-5110c1252fa881bd90f516357ca6c31cb88d9342.zip |
Revert "Revert "Add chassis identify ipmi command.""
This reverts commit 82feb17d0c244ed04b82b0fbed3c0a9456986a86.
The fix for armv5 futures is provided in yocto 2.4
Resolves openbmc/openbmc#3010
Change-Id: Ifc7e224f6f1fa115e0299642e8866b82d6e4f38c
-rw-r--r-- | chassishandler.cpp | 115 | ||||
-rw-r--r-- | chassishandler.h | 5 |
2 files changed, 118 insertions, 2 deletions
diff --git a/chassishandler.cpp b/chassishandler.cpp index 0eef0a0..43c3fe3 100644 --- a/chassishandler.cpp +++ b/chassishandler.cpp @@ -17,6 +17,8 @@ #include <sstream> #include <array> #include <fstream> +#include <future> +#include <chrono> #include <experimental/filesystem> #include <string> #include <map> @@ -47,6 +49,7 @@ constexpr size_t SIZE_PREFIX = 7; constexpr size_t MAX_PREFIX_VALUE = 32; constexpr size_t SIZE_COOKIE = 4; constexpr size_t SIZE_VERSION = 2; +constexpr size_t DEFAULT_IDENTIFY_TIME_OUT = 15; //PetiBoot-Specific static constexpr uint8_t net_conf_initial_bytes[] = {0x80, 0x21, 0x70, 0x62, @@ -67,6 +70,8 @@ void register_netfn_chassis_functions() __attribute__((constructor)); const char *settings_object_name = "/org/openbmc/settings/host0"; const char *settings_intf_name = "org.freedesktop.DBus.Properties"; const char *host_intf_name = "org.openbmc.settings.Host"; +const char *identify_led_object_name = + "/xyz/openbmc_project/led/groups/enclosure_identify"; constexpr auto SETTINGS_ROOT = "/"; constexpr auto SETTINGS_MATCH = "host0"; @@ -1025,6 +1030,111 @@ ipmi_ret_t ipmi_chassis_control(ipmi_netfn_t netfn, ipmi_cmd_t cmd, return ( (rc < 0) ? IPMI_CC_INVALID : IPMI_CC_OK); } +ipmi_ret_t ipmi_chassis_identify(ipmi_netfn_t netfn, ipmi_cmd_t cmd, + ipmi_request_t request, + ipmi_response_t response, + ipmi_data_len_t data_len, + ipmi_context_t context) +{ + static std::atomic_size_t currentCallerId(0); + static std::unique_ptr<std::future<void>> future; + static std::condition_variable condition; + static std::mutex timeoutMutex; + + if (*data_len > 2) + { + return IPMI_CC_REQ_DATA_LEN_INVALID; + } + uint8_t identifyInterval = *data_len > 0 ? + (static_cast<uint8_t*>(request))[0] : + DEFAULT_IDENTIFY_TIME_OUT; + bool forceIdentify = + *data_len == 2 ? (static_cast<uint8_t*>(request))[1] & 0x01 : false; + + currentCallerId++; + + // stop any threads currently running + condition.notify_all(); + + // lookup enclosure_identify group owner(s) in mapper + auto mapperCall = chassis::internal::dbus.new_method_call( + ipmi::MAPPER_BUS_NAME, + ipmi::MAPPER_OBJ, + ipmi::MAPPER_INTF, + "GetObject"); + + mapperCall.append(identify_led_object_name); + static const std::vector<std::string> interfaces = + { + "xyz.openbmc_project.Led.Group" + }; + mapperCall.append(interfaces); + auto mapperReply = chassis::internal::dbus.call(mapperCall); + if (mapperReply.is_method_error()) + { + log<level::ERR>("Chassis Identify: Error communicating to mapper."); + return IPMI_CC_RESPONSE_ERROR; + } + std::vector<std::pair<std::string, std::vector<std::string>>> mapperResp; + mapperReply.read(mapperResp); + + for (auto& object : mapperResp) + { + std::string& connection = object.first; + + if (identifyInterval || forceIdentify) + { + auto ledOn = chassis::internal::dbus.new_method_call( + connection.c_str(), + identify_led_object_name, + "org.freedesktop.DBus.Properties", "Set"); + ledOn.append( + "xyz.openbmc_project.Led.Group", "Asserted", + sdbusplus::message::variant<bool>( + true)); + auto ledReply = chassis::internal::dbus.call(ledOn); + if (ledReply.is_method_error()) + { + log<level::ERR>("Chassis Identify: Error Setting State On\n"); + return IPMI_CC_RESPONSE_ERROR; + } + if (forceIdentify) + { + return IPMI_CC_OK; + } + } + + size_t threadCallerId = currentCallerId; + future = std::make_unique<std::future<void>>( + std::async(std::launch::async, + [connection, + identifyInterval, + threadCallerId] + { + std::unique_lock<std::mutex> lock(timeoutMutex); + if (condition.wait_for(lock, + std::chrono::seconds(identifyInterval), + [&threadCallerId]{return currentCallerId != threadCallerId;})) + { + return; // another thread started. + } + auto ledOff = chassis::internal::dbus.new_method_call( + connection.c_str(), + identify_led_object_name, + "org.freedesktop.DBus.Properties", "Set"); + ledOff.append("xyz.openbmc_project.Led.Group", "Asserted", + sdbusplus::message::variant<bool>( + false)); + auto ledReply = chassis::internal::dbus.call(ledOff); + if (ledReply.is_method_error()) + { + log<level::ERR>("Chassis Identify: Error Setting State Off\n"); + } + })); + } + return IPMI_CC_OK; +} + namespace boot_options { @@ -1377,6 +1487,11 @@ void register_netfn_chassis_functions() ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_CHASSIS_CONTROL, NULL, ipmi_chassis_control, PRIVILEGE_OPERATOR); + // <Chassis Identify> + printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_CHASSIS, IPMI_CMD_CHASSIS_IDENTIFY); + ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_CHASSIS_IDENTIFY, NULL, + ipmi_chassis_identify, PRIVILEGE_OPERATOR); + // <Set System Boot Options> printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n", NETFUN_CHASSIS, IPMI_CMD_SET_SYS_BOOT_OPTIONS); ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_SET_SYS_BOOT_OPTIONS, NULL, diff --git a/chassishandler.h b/chassishandler.h index 528a05d..c626158 100644 --- a/chassishandler.h +++ b/chassishandler.h @@ -10,8 +10,9 @@ enum ipmi_netfn_app_cmds IPMI_CMD_GET_CHASSIS_CAP = 0x00, // Chassis Status IPMI_CMD_CHASSIS_STATUS = 0x01, - // Chassis Control - IPMI_CMD_CHASSIS_CONTROL = 0x02, + // Chassis Control + IPMI_CMD_CHASSIS_CONTROL = 0x02, + IPMI_CMD_CHASSIS_IDENTIFY = 0x04, // Get capability bits IPMI_CMD_SET_SYS_BOOT_OPTIONS = 0x08, IPMI_CMD_GET_SYS_BOOT_OPTIONS = 0x09, |