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>
2494e9d1a8SQiang XU #include <string>
2594e9d1a8SQiang XU 
2694e9d1a8SQiang XU namespace ipmi
2794e9d1a8SQiang XU {
2894e9d1a8SQiang XU void registerMultiNodeFunctions() __attribute__((constructor));
2994e9d1a8SQiang XU 
3094e9d1a8SQiang XU std::optional<uint8_t> getMultiNodeInfo(std::string name)
3194e9d1a8SQiang XU {
3294e9d1a8SQiang XU     auto pdbus = getSdBus();
3394e9d1a8SQiang XU     try
3494e9d1a8SQiang XU     {
3594e9d1a8SQiang XU         std::string service =
3694e9d1a8SQiang XU             getService(*pdbus, multiNodeIntf, multiNodeObjPath);
3794e9d1a8SQiang XU         Value dbusValue = getDbusProperty(*pdbus, service, multiNodeObjPath,
3894e9d1a8SQiang XU                                           multiNodeIntf, name);
3994e9d1a8SQiang XU         return std::get<uint8_t>(dbusValue);
4094e9d1a8SQiang XU     }
4194e9d1a8SQiang XU     catch (const std::exception& e)
4294e9d1a8SQiang XU     {
4394e9d1a8SQiang XU         phosphor::logging::log<phosphor::logging::level::ERR>(
4494e9d1a8SQiang XU             "getMultiNodeInfo: can't get multi node info from dbus!",
4594e9d1a8SQiang XU             phosphor::logging::entry("ERR=%s", e.what()));
4694e9d1a8SQiang XU         return std::nullopt;
4794e9d1a8SQiang XU     }
4894e9d1a8SQiang XU }
4994e9d1a8SQiang XU 
5094e9d1a8SQiang XU std::optional<uint8_t> getMultiNodeRole()
5194e9d1a8SQiang XU {
5294e9d1a8SQiang XU     auto pdbus = getSdBus();
5394e9d1a8SQiang XU     try
5494e9d1a8SQiang XU     {
5594e9d1a8SQiang XU         std::string service =
5694e9d1a8SQiang XU             getService(*pdbus, multiNodeIntf, multiNodeObjPath);
5794e9d1a8SQiang XU         Value dbusValue = getDbusProperty(*pdbus, service, multiNodeObjPath,
5894e9d1a8SQiang XU                                           multiNodeIntf, "NodeRole");
5994e9d1a8SQiang XU         std::string valueStr = std::get<std::string>(dbusValue);
6094e9d1a8SQiang XU         uint8_t value;
6194e9d1a8SQiang XU         if (valueStr == "single")
6294e9d1a8SQiang XU             value = static_cast<uint8_t>(NodeRole::single);
6394e9d1a8SQiang XU         else if (valueStr == "master")
6494e9d1a8SQiang XU             value = static_cast<uint8_t>(NodeRole::master);
6594e9d1a8SQiang XU         else if (valueStr == "slave")
6694e9d1a8SQiang XU             value = static_cast<uint8_t>(NodeRole::slave);
6794e9d1a8SQiang XU         else if (valueStr == "arbitrating")
6894e9d1a8SQiang XU             value = static_cast<uint8_t>(NodeRole::arbitrating);
6994e9d1a8SQiang XU         return value;
7094e9d1a8SQiang XU     }
7194e9d1a8SQiang XU     catch (const std::exception& e)
7294e9d1a8SQiang XU     {
7394e9d1a8SQiang XU         phosphor::logging::log<phosphor::logging::level::ERR>(
7494e9d1a8SQiang XU             "getMultiNodeRole: can't get multi node role from dbus!",
7594e9d1a8SQiang XU             phosphor::logging::entry("ERR=%s", e.what()));
7694e9d1a8SQiang XU         return std::nullopt;
7794e9d1a8SQiang XU     }
7894e9d1a8SQiang XU }
7994e9d1a8SQiang XU 
8094e9d1a8SQiang XU ipmi::RspType<uint8_t> ipmiGetMultiNodePresence()
8194e9d1a8SQiang XU 
8294e9d1a8SQiang XU {
8394e9d1a8SQiang XU     std::optional<uint8_t> nodeInfo = getMultiNodeInfo("NodePresence");
8494e9d1a8SQiang XU     if (!nodeInfo)
8594e9d1a8SQiang XU     {
8694e9d1a8SQiang XU         return ipmi::responseResponseError();
8794e9d1a8SQiang XU     }
8894e9d1a8SQiang XU 
8994e9d1a8SQiang XU     return ipmi::responseSuccess(*nodeInfo);
9094e9d1a8SQiang XU }
9194e9d1a8SQiang XU 
9294e9d1a8SQiang XU ipmi::RspType<uint8_t> ipmiGetMultiNodeId()
9394e9d1a8SQiang XU {
9494e9d1a8SQiang XU     std::optional<uint8_t> nodeInfo = getMultiNodeInfo("NodeId");
9594e9d1a8SQiang XU     if (!nodeInfo)
9694e9d1a8SQiang XU     {
9794e9d1a8SQiang XU         return ipmi::responseResponseError();
9894e9d1a8SQiang XU     }
9994e9d1a8SQiang XU 
10094e9d1a8SQiang XU     return ipmi::responseSuccess(*nodeInfo);
10194e9d1a8SQiang XU }
10294e9d1a8SQiang XU 
10394e9d1a8SQiang XU ipmi::RspType<uint8_t> ipmiGetMultiNodeRole()
10494e9d1a8SQiang XU {
10594e9d1a8SQiang XU     std::optional<uint8_t> nodeInfo = getMultiNodeRole();
10694e9d1a8SQiang XU     if (!nodeInfo)
10794e9d1a8SQiang XU     {
10894e9d1a8SQiang XU         return ipmi::responseResponseError();
10994e9d1a8SQiang XU     }
11094e9d1a8SQiang XU 
11194e9d1a8SQiang XU     return ipmi::responseSuccess(*nodeInfo);
11294e9d1a8SQiang XU }
11394e9d1a8SQiang XU 
11494e9d1a8SQiang XU void registerMultiNodeFunctions(void)
11594e9d1a8SQiang XU {
11694e9d1a8SQiang XU     phosphor::logging::log<phosphor::logging::level::INFO>(
11794e9d1a8SQiang XU         "Registering MultiNode commands");
11894e9d1a8SQiang XU 
119*98bbf69aSVernon Mauery     ipmi::registerHandler(ipmi::prioOemBase, ipmi::intel::netFnGeneral,
120*98bbf69aSVernon Mauery                           ipmi::intel::general::cmdGetMultiNodePresence,
12194e9d1a8SQiang XU                           ipmi::Privilege::User, ipmiGetMultiNodePresence);
12294e9d1a8SQiang XU 
123*98bbf69aSVernon Mauery     ipmi::registerHandler(ipmi::prioOemBase, ipmi::intel::netFnGeneral,
124*98bbf69aSVernon Mauery                           ipmi::intel::general::cmdGetMultiNodeId,
12594e9d1a8SQiang XU                           ipmi::Privilege::User, ipmiGetMultiNodeId);
12694e9d1a8SQiang XU 
127*98bbf69aSVernon Mauery     ipmi::registerHandler(ipmi::prioOemBase, ipmi::intel::netFnGeneral,
128*98bbf69aSVernon Mauery                           ipmi::intel::general::cmdGetMultiNodeRole,
12994e9d1a8SQiang XU                           ipmi::Privilege::User, ipmiGetMultiNodeRole);
13094e9d1a8SQiang XU }
13194e9d1a8SQiang XU 
13294e9d1a8SQiang XU } // namespace ipmi
133