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 25 #include <string> 26 27 namespace ipmi 28 { 29 void registerMultiNodeFunctions() __attribute__((constructor)); 30 31 std::optional<uint8_t> getMultiNodeInfo(std::string name) 32 { 33 auto pdbus = getSdBus(); 34 try 35 { 36 std::string service = getService(*pdbus, multiNodeIntf, 37 multiNodeObjPath); 38 Value dbusValue = getDbusProperty(*pdbus, service, multiNodeObjPath, 39 multiNodeIntf, name); 40 return std::get<uint8_t>(dbusValue); 41 } 42 catch (const std::exception& e) 43 { 44 phosphor::logging::log<phosphor::logging::level::ERR>( 45 "getMultiNodeInfo: can't get multi node info from dbus!", 46 phosphor::logging::entry("ERR=%s", e.what())); 47 return std::nullopt; 48 } 49 } 50 51 std::optional<uint8_t> getMultiNodeRole() 52 { 53 auto pdbus = getSdBus(); 54 try 55 { 56 std::string service = getService(*pdbus, multiNodeIntf, 57 multiNodeObjPath); 58 Value dbusValue = getDbusProperty(*pdbus, service, multiNodeObjPath, 59 multiNodeIntf, "NodeRole"); 60 std::string valueStr = std::get<std::string>(dbusValue); 61 uint8_t value; 62 if (valueStr == "single") 63 value = static_cast<uint8_t>(NodeRole::single); 64 else if (valueStr == "master") 65 value = static_cast<uint8_t>(NodeRole::controller); 66 else if (valueStr == "slave") 67 value = static_cast<uint8_t>(NodeRole::target); 68 else if (valueStr == "arbitrating") 69 value = static_cast<uint8_t>(NodeRole::arbitrating); 70 else 71 { 72 phosphor::logging::log<phosphor::logging::level::ERR>( 73 "getMultiNodeRole: Invalid dbus value!", 74 phosphor::logging::entry("VALUE=%s", valueStr.c_str())); 75 return std::nullopt; 76 } 77 return value; 78 } 79 catch (const std::exception& e) 80 { 81 phosphor::logging::log<phosphor::logging::level::ERR>( 82 "getMultiNodeRole: can't get multi node role from dbus!", 83 phosphor::logging::entry("ERR=%s", e.what())); 84 return std::nullopt; 85 } 86 } 87 88 ipmi::RspType<uint8_t> ipmiGetMultiNodePresence() 89 90 { 91 std::optional<uint8_t> nodeInfo = getMultiNodeInfo("NodePresence"); 92 if (!nodeInfo) 93 { 94 return ipmi::responseResponseError(); 95 } 96 97 return ipmi::responseSuccess(*nodeInfo); 98 } 99 100 ipmi::RspType<uint8_t> ipmiGetMultiNodeId() 101 { 102 std::optional<uint8_t> nodeInfo = getMultiNodeInfo("NodeId"); 103 if (!nodeInfo) 104 { 105 return ipmi::responseResponseError(); 106 } 107 108 return ipmi::responseSuccess(*nodeInfo); 109 } 110 111 ipmi::RspType<uint8_t> ipmiGetMultiNodeRole() 112 { 113 std::optional<uint8_t> nodeInfo = getMultiNodeRole(); 114 if (!nodeInfo) 115 { 116 return ipmi::responseResponseError(); 117 } 118 119 return ipmi::responseSuccess(*nodeInfo); 120 } 121 122 void registerMultiNodeFunctions(void) 123 { 124 phosphor::logging::log<phosphor::logging::level::INFO>( 125 "Registering MultiNode commands"); 126 127 ipmi::registerHandler(ipmi::prioOemBase, ipmi::intel::netFnGeneral, 128 ipmi::intel::general::cmdGetMultiNodePresence, 129 ipmi::Privilege::User, ipmiGetMultiNodePresence); 130 131 ipmi::registerHandler(ipmi::prioOemBase, ipmi::intel::netFnGeneral, 132 ipmi::intel::general::cmdGetMultiNodeId, 133 ipmi::Privilege::User, ipmiGetMultiNodeId); 134 135 ipmi::registerHandler(ipmi::prioOemBase, ipmi::intel::netFnGeneral, 136 ipmi::intel::general::cmdGetMultiNodeRole, 137 ipmi::Privilege::User, ipmiGetMultiNodeRole); 138 } 139 140 } // namespace ipmi 141