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