1*94e9d1a8SQiang XU /* 2*94e9d1a8SQiang XU // Copyright (c) 2019 Intel Corporation 3*94e9d1a8SQiang XU // 4*94e9d1a8SQiang XU // Licensed under the Apache License, Version 2.0 (the "License"); 5*94e9d1a8SQiang XU // you may not use this file except in compliance with the License. 6*94e9d1a8SQiang XU // You may obtain a copy of the License at 7*94e9d1a8SQiang XU // 8*94e9d1a8SQiang XU // http://www.apache.org/licenses/LICENSE-2.0 9*94e9d1a8SQiang XU // 10*94e9d1a8SQiang XU // Unless required by applicable law or agreed to in writing, software 11*94e9d1a8SQiang XU // distributed under the License is distributed on an "AS IS" BASIS, 12*94e9d1a8SQiang XU // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*94e9d1a8SQiang XU // See the License for the specific language governing permissions and 14*94e9d1a8SQiang XU // limitations under the License. 15*94e9d1a8SQiang XU */ 16*94e9d1a8SQiang XU 17*94e9d1a8SQiang XU #include <ipmid/api.hpp> 18*94e9d1a8SQiang XU #include <ipmid/utils.hpp> 19*94e9d1a8SQiang XU #include <multinodecommands.hpp> 20*94e9d1a8SQiang XU #include <oemcommands.hpp> 21*94e9d1a8SQiang XU #include <phosphor-logging/log.hpp> 22*94e9d1a8SQiang XU #include <sdbusplus/bus.hpp> 23*94e9d1a8SQiang XU #include <sdbusplus/message/types.hpp> 24*94e9d1a8SQiang XU #include <string> 25*94e9d1a8SQiang XU 26*94e9d1a8SQiang XU namespace ipmi 27*94e9d1a8SQiang XU { 28*94e9d1a8SQiang XU void registerMultiNodeFunctions() __attribute__((constructor)); 29*94e9d1a8SQiang XU 30*94e9d1a8SQiang XU std::optional<uint8_t> getMultiNodeInfo(std::string name) 31*94e9d1a8SQiang XU { 32*94e9d1a8SQiang XU auto pdbus = getSdBus(); 33*94e9d1a8SQiang XU try 34*94e9d1a8SQiang XU { 35*94e9d1a8SQiang XU std::string service = 36*94e9d1a8SQiang XU getService(*pdbus, multiNodeIntf, multiNodeObjPath); 37*94e9d1a8SQiang XU Value dbusValue = getDbusProperty(*pdbus, service, multiNodeObjPath, 38*94e9d1a8SQiang XU multiNodeIntf, name); 39*94e9d1a8SQiang XU return std::get<uint8_t>(dbusValue); 40*94e9d1a8SQiang XU } 41*94e9d1a8SQiang XU catch (const std::exception& e) 42*94e9d1a8SQiang XU { 43*94e9d1a8SQiang XU phosphor::logging::log<phosphor::logging::level::ERR>( 44*94e9d1a8SQiang XU "getMultiNodeInfo: can't get multi node info from dbus!", 45*94e9d1a8SQiang XU phosphor::logging::entry("ERR=%s", e.what())); 46*94e9d1a8SQiang XU return std::nullopt; 47*94e9d1a8SQiang XU } 48*94e9d1a8SQiang XU } 49*94e9d1a8SQiang XU 50*94e9d1a8SQiang XU std::optional<uint8_t> getMultiNodeRole() 51*94e9d1a8SQiang XU { 52*94e9d1a8SQiang XU auto pdbus = getSdBus(); 53*94e9d1a8SQiang XU try 54*94e9d1a8SQiang XU { 55*94e9d1a8SQiang XU std::string service = 56*94e9d1a8SQiang XU getService(*pdbus, multiNodeIntf, multiNodeObjPath); 57*94e9d1a8SQiang XU Value dbusValue = getDbusProperty(*pdbus, service, multiNodeObjPath, 58*94e9d1a8SQiang XU multiNodeIntf, "NodeRole"); 59*94e9d1a8SQiang XU std::string valueStr = std::get<std::string>(dbusValue); 60*94e9d1a8SQiang XU uint8_t value; 61*94e9d1a8SQiang XU if (valueStr == "single") 62*94e9d1a8SQiang XU value = static_cast<uint8_t>(NodeRole::single); 63*94e9d1a8SQiang XU else if (valueStr == "master") 64*94e9d1a8SQiang XU value = static_cast<uint8_t>(NodeRole::master); 65*94e9d1a8SQiang XU else if (valueStr == "slave") 66*94e9d1a8SQiang XU value = static_cast<uint8_t>(NodeRole::slave); 67*94e9d1a8SQiang XU else if (valueStr == "arbitrating") 68*94e9d1a8SQiang XU value = static_cast<uint8_t>(NodeRole::arbitrating); 69*94e9d1a8SQiang XU return value; 70*94e9d1a8SQiang XU } 71*94e9d1a8SQiang XU catch (const std::exception& e) 72*94e9d1a8SQiang XU { 73*94e9d1a8SQiang XU phosphor::logging::log<phosphor::logging::level::ERR>( 74*94e9d1a8SQiang XU "getMultiNodeRole: can't get multi node role from dbus!", 75*94e9d1a8SQiang XU phosphor::logging::entry("ERR=%s", e.what())); 76*94e9d1a8SQiang XU return std::nullopt; 77*94e9d1a8SQiang XU } 78*94e9d1a8SQiang XU } 79*94e9d1a8SQiang XU 80*94e9d1a8SQiang XU ipmi::RspType<uint8_t> ipmiGetMultiNodePresence() 81*94e9d1a8SQiang XU 82*94e9d1a8SQiang XU { 83*94e9d1a8SQiang XU std::optional<uint8_t> nodeInfo = getMultiNodeInfo("NodePresence"); 84*94e9d1a8SQiang XU if (!nodeInfo) 85*94e9d1a8SQiang XU { 86*94e9d1a8SQiang XU return ipmi::responseResponseError(); 87*94e9d1a8SQiang XU } 88*94e9d1a8SQiang XU 89*94e9d1a8SQiang XU return ipmi::responseSuccess(*nodeInfo); 90*94e9d1a8SQiang XU } 91*94e9d1a8SQiang XU 92*94e9d1a8SQiang XU ipmi::RspType<uint8_t> ipmiGetMultiNodeId() 93*94e9d1a8SQiang XU { 94*94e9d1a8SQiang XU std::optional<uint8_t> nodeInfo = getMultiNodeInfo("NodeId"); 95*94e9d1a8SQiang XU if (!nodeInfo) 96*94e9d1a8SQiang XU { 97*94e9d1a8SQiang XU return ipmi::responseResponseError(); 98*94e9d1a8SQiang XU } 99*94e9d1a8SQiang XU 100*94e9d1a8SQiang XU return ipmi::responseSuccess(*nodeInfo); 101*94e9d1a8SQiang XU } 102*94e9d1a8SQiang XU 103*94e9d1a8SQiang XU ipmi::RspType<uint8_t> ipmiGetMultiNodeRole() 104*94e9d1a8SQiang XU { 105*94e9d1a8SQiang XU std::optional<uint8_t> nodeInfo = getMultiNodeRole(); 106*94e9d1a8SQiang XU if (!nodeInfo) 107*94e9d1a8SQiang XU { 108*94e9d1a8SQiang XU return ipmi::responseResponseError(); 109*94e9d1a8SQiang XU } 110*94e9d1a8SQiang XU 111*94e9d1a8SQiang XU return ipmi::responseSuccess(*nodeInfo); 112*94e9d1a8SQiang XU } 113*94e9d1a8SQiang XU 114*94e9d1a8SQiang XU void registerMultiNodeFunctions(void) 115*94e9d1a8SQiang XU { 116*94e9d1a8SQiang XU phosphor::logging::log<phosphor::logging::level::INFO>( 117*94e9d1a8SQiang XU "Registering MultiNode commands"); 118*94e9d1a8SQiang XU 119*94e9d1a8SQiang XU ipmi::registerHandler( 120*94e9d1a8SQiang XU ipmi::prioOemBase, ipmi::netFnOemOne, 121*94e9d1a8SQiang XU static_cast<ipmi::Cmd>(IPMINetfnMultiNodeCmd::cmdGetMultiNodePresence), 122*94e9d1a8SQiang XU ipmi::Privilege::User, ipmiGetMultiNodePresence); 123*94e9d1a8SQiang XU 124*94e9d1a8SQiang XU ipmi::registerHandler( 125*94e9d1a8SQiang XU ipmi::prioOemBase, ipmi::netFnOemOne, 126*94e9d1a8SQiang XU static_cast<ipmi::Cmd>(IPMINetfnMultiNodeCmd::cmdGetMultiNodeId), 127*94e9d1a8SQiang XU ipmi::Privilege::User, ipmiGetMultiNodeId); 128*94e9d1a8SQiang XU 129*94e9d1a8SQiang XU ipmi::registerHandler( 130*94e9d1a8SQiang XU ipmi::prioOemBase, ipmi::netFnOemOne, 131*94e9d1a8SQiang XU static_cast<ipmi::Cmd>(IPMINetfnMultiNodeCmd::cmdGetMultiNodeRole), 132*94e9d1a8SQiang XU ipmi::Privilege::User, ipmiGetMultiNodeRole); 133*94e9d1a8SQiang XU } 134*94e9d1a8SQiang XU 135*94e9d1a8SQiang XU } // namespace ipmi 136