194e9d1a8SQiang XU /* 294e9d1a8SQiang XU // Copyright (c) 2019 Intel Corporation 394e9d1a8SQiang XU // 494e9d1a8SQiang XU // Licensed under the Apache License, Version 2.0 (the "License"); 594e9d1a8SQiang XU // you may not use this file except in compliance with the License. 694e9d1a8SQiang XU // You may obtain a copy of the License at 794e9d1a8SQiang XU // 894e9d1a8SQiang XU // http://www.apache.org/licenses/LICENSE-2.0 994e9d1a8SQiang XU // 1094e9d1a8SQiang XU // Unless required by applicable law or agreed to in writing, software 1194e9d1a8SQiang XU // distributed under the License is distributed on an "AS IS" BASIS, 1294e9d1a8SQiang XU // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1394e9d1a8SQiang XU // See the License for the specific language governing permissions and 1494e9d1a8SQiang XU // limitations under the License. 1594e9d1a8SQiang XU */ 1694e9d1a8SQiang XU 1794e9d1a8SQiang XU #include <ipmid/api.hpp> 1894e9d1a8SQiang XU #include <ipmid/utils.hpp> 1994e9d1a8SQiang XU #include <multinodecommands.hpp> 2094e9d1a8SQiang XU #include <oemcommands.hpp> 2194e9d1a8SQiang XU #include <phosphor-logging/log.hpp> 2294e9d1a8SQiang XU #include <sdbusplus/bus.hpp> 2394e9d1a8SQiang XU #include <sdbusplus/message/types.hpp> 24fcd2d3a9SJames Feist 2594e9d1a8SQiang XU #include <string> 2694e9d1a8SQiang XU 2794e9d1a8SQiang XU namespace ipmi 2894e9d1a8SQiang XU { 2994e9d1a8SQiang XU void registerMultiNodeFunctions() __attribute__((constructor)); 3094e9d1a8SQiang XU 3194e9d1a8SQiang XU std::optional<uint8_t> getMultiNodeInfo(std::string name) 3294e9d1a8SQiang XU { 3394e9d1a8SQiang XU auto pdbus = getSdBus(); 3494e9d1a8SQiang XU try 3594e9d1a8SQiang XU { 36*b37abfb2SPatrick Williams std::string service = getService(*pdbus, multiNodeIntf, 37*b37abfb2SPatrick Williams multiNodeObjPath); 3894e9d1a8SQiang XU Value dbusValue = getDbusProperty(*pdbus, service, multiNodeObjPath, 3994e9d1a8SQiang XU multiNodeIntf, name); 4094e9d1a8SQiang XU return std::get<uint8_t>(dbusValue); 4194e9d1a8SQiang XU } 4294e9d1a8SQiang XU catch (const std::exception& e) 4394e9d1a8SQiang XU { 4494e9d1a8SQiang XU phosphor::logging::log<phosphor::logging::level::ERR>( 4594e9d1a8SQiang XU "getMultiNodeInfo: can't get multi node info from dbus!", 4694e9d1a8SQiang XU phosphor::logging::entry("ERR=%s", e.what())); 4794e9d1a8SQiang XU return std::nullopt; 4894e9d1a8SQiang XU } 4994e9d1a8SQiang XU } 5094e9d1a8SQiang XU 5194e9d1a8SQiang XU std::optional<uint8_t> getMultiNodeRole() 5294e9d1a8SQiang XU { 5394e9d1a8SQiang XU auto pdbus = getSdBus(); 5494e9d1a8SQiang XU try 5594e9d1a8SQiang XU { 56*b37abfb2SPatrick Williams std::string service = getService(*pdbus, multiNodeIntf, 57*b37abfb2SPatrick Williams multiNodeObjPath); 5894e9d1a8SQiang XU Value dbusValue = getDbusProperty(*pdbus, service, multiNodeObjPath, 5994e9d1a8SQiang XU multiNodeIntf, "NodeRole"); 6094e9d1a8SQiang XU std::string valueStr = std::get<std::string>(dbusValue); 6194e9d1a8SQiang XU uint8_t value; 6294e9d1a8SQiang XU if (valueStr == "single") 6394e9d1a8SQiang XU value = static_cast<uint8_t>(NodeRole::single); 6494e9d1a8SQiang XU else if (valueStr == "master") 6580d4d5f9SMatt Simmering value = static_cast<uint8_t>(NodeRole::controller); 6694e9d1a8SQiang XU else if (valueStr == "slave") 6780d4d5f9SMatt Simmering value = static_cast<uint8_t>(NodeRole::target); 6894e9d1a8SQiang XU else if (valueStr == "arbitrating") 6994e9d1a8SQiang XU value = static_cast<uint8_t>(NodeRole::arbitrating); 7036ed8d24SP Dheeraj Srujan Kumar else 7136ed8d24SP Dheeraj Srujan Kumar { 7236ed8d24SP Dheeraj Srujan Kumar phosphor::logging::log<phosphor::logging::level::ERR>( 7336ed8d24SP Dheeraj Srujan Kumar "getMultiNodeRole: Invalid dbus value!", 7436ed8d24SP Dheeraj Srujan Kumar phosphor::logging::entry("VALUE=%s", valueStr.c_str())); 7536ed8d24SP Dheeraj Srujan Kumar return std::nullopt; 7636ed8d24SP Dheeraj Srujan Kumar } 7794e9d1a8SQiang XU return value; 7894e9d1a8SQiang XU } 7994e9d1a8SQiang XU catch (const std::exception& e) 8094e9d1a8SQiang XU { 8194e9d1a8SQiang XU phosphor::logging::log<phosphor::logging::level::ERR>( 8294e9d1a8SQiang XU "getMultiNodeRole: can't get multi node role from dbus!", 8394e9d1a8SQiang XU phosphor::logging::entry("ERR=%s", e.what())); 8494e9d1a8SQiang XU return std::nullopt; 8594e9d1a8SQiang XU } 8694e9d1a8SQiang XU } 8794e9d1a8SQiang XU 8894e9d1a8SQiang XU ipmi::RspType<uint8_t> ipmiGetMultiNodePresence() 8994e9d1a8SQiang XU 9094e9d1a8SQiang XU { 9194e9d1a8SQiang XU std::optional<uint8_t> nodeInfo = getMultiNodeInfo("NodePresence"); 9294e9d1a8SQiang XU if (!nodeInfo) 9394e9d1a8SQiang XU { 9494e9d1a8SQiang XU return ipmi::responseResponseError(); 9594e9d1a8SQiang XU } 9694e9d1a8SQiang XU 9794e9d1a8SQiang XU return ipmi::responseSuccess(*nodeInfo); 9894e9d1a8SQiang XU } 9994e9d1a8SQiang XU 10094e9d1a8SQiang XU ipmi::RspType<uint8_t> ipmiGetMultiNodeId() 10194e9d1a8SQiang XU { 10294e9d1a8SQiang XU std::optional<uint8_t> nodeInfo = getMultiNodeInfo("NodeId"); 10394e9d1a8SQiang XU if (!nodeInfo) 10494e9d1a8SQiang XU { 10594e9d1a8SQiang XU return ipmi::responseResponseError(); 10694e9d1a8SQiang XU } 10794e9d1a8SQiang XU 10894e9d1a8SQiang XU return ipmi::responseSuccess(*nodeInfo); 10994e9d1a8SQiang XU } 11094e9d1a8SQiang XU 11194e9d1a8SQiang XU ipmi::RspType<uint8_t> ipmiGetMultiNodeRole() 11294e9d1a8SQiang XU { 11394e9d1a8SQiang XU std::optional<uint8_t> nodeInfo = getMultiNodeRole(); 11494e9d1a8SQiang XU if (!nodeInfo) 11594e9d1a8SQiang XU { 11694e9d1a8SQiang XU return ipmi::responseResponseError(); 11794e9d1a8SQiang XU } 11894e9d1a8SQiang XU 11994e9d1a8SQiang XU return ipmi::responseSuccess(*nodeInfo); 12094e9d1a8SQiang XU } 12194e9d1a8SQiang XU 12294e9d1a8SQiang XU void registerMultiNodeFunctions(void) 12394e9d1a8SQiang XU { 12494e9d1a8SQiang XU phosphor::logging::log<phosphor::logging::level::INFO>( 12594e9d1a8SQiang XU "Registering MultiNode commands"); 12694e9d1a8SQiang XU 12798bbf69aSVernon Mauery ipmi::registerHandler(ipmi::prioOemBase, ipmi::intel::netFnGeneral, 12898bbf69aSVernon Mauery ipmi::intel::general::cmdGetMultiNodePresence, 12994e9d1a8SQiang XU ipmi::Privilege::User, ipmiGetMultiNodePresence); 13094e9d1a8SQiang XU 13198bbf69aSVernon Mauery ipmi::registerHandler(ipmi::prioOemBase, ipmi::intel::netFnGeneral, 13298bbf69aSVernon Mauery ipmi::intel::general::cmdGetMultiNodeId, 13394e9d1a8SQiang XU ipmi::Privilege::User, ipmiGetMultiNodeId); 13494e9d1a8SQiang XU 13598bbf69aSVernon Mauery ipmi::registerHandler(ipmi::prioOemBase, ipmi::intel::netFnGeneral, 13698bbf69aSVernon Mauery ipmi::intel::general::cmdGetMultiNodeRole, 13794e9d1a8SQiang XU ipmi::Privilege::User, ipmiGetMultiNodeRole); 13894e9d1a8SQiang XU } 13994e9d1a8SQiang XU 14094e9d1a8SQiang XU } // namespace ipmi 141