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
getMultiNodeInfo(std::string name)31 std::optional<uint8_t> getMultiNodeInfo(std::string name)
32 {
33 auto pdbus = getSdBus();
34 try
35 {
36 std::string service =
37 getService(*pdbus, multiNodeIntf, 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
getMultiNodeRole()51 std::optional<uint8_t> getMultiNodeRole()
52 {
53 auto pdbus = getSdBus();
54 try
55 {
56 std::string service =
57 getService(*pdbus, multiNodeIntf, 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
ipmiGetMultiNodePresence()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
ipmiGetMultiNodeId()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
ipmiGetMultiNodeRole()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
registerMultiNodeFunctions(void)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