blob: d6712b321eab8b588c96390b866aa0668da56fef [file] [log] [blame]
/*
// Copyright (c) 2019 Intel Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
*/
#include <ipmid/api.hpp>
#include <ipmid/utils.hpp>
#include <multinodecommands.hpp>
#include <oemcommands.hpp>
#include <phosphor-logging/log.hpp>
#include <sdbusplus/bus.hpp>
#include <sdbusplus/message/types.hpp>
#include <string>
namespace ipmi
{
void registerMultiNodeFunctions() __attribute__((constructor));
std::optional<uint8_t> getMultiNodeInfo(std::string name)
{
auto pdbus = getSdBus();
try
{
std::string service =
getService(*pdbus, multiNodeIntf, multiNodeObjPath);
Value dbusValue = getDbusProperty(*pdbus, service, multiNodeObjPath,
multiNodeIntf, name);
return std::get<uint8_t>(dbusValue);
}
catch (const std::exception& e)
{
phosphor::logging::log<phosphor::logging::level::ERR>(
"getMultiNodeInfo: can't get multi node info from dbus!",
phosphor::logging::entry("ERR=%s", e.what()));
return std::nullopt;
}
}
std::optional<uint8_t> getMultiNodeRole()
{
auto pdbus = getSdBus();
try
{
std::string service =
getService(*pdbus, multiNodeIntf, multiNodeObjPath);
Value dbusValue = getDbusProperty(*pdbus, service, multiNodeObjPath,
multiNodeIntf, "NodeRole");
std::string valueStr = std::get<std::string>(dbusValue);
uint8_t value;
if (valueStr == "single")
value = static_cast<uint8_t>(NodeRole::single);
else if (valueStr == "master")
value = static_cast<uint8_t>(NodeRole::controller);
else if (valueStr == "slave")
value = static_cast<uint8_t>(NodeRole::target);
else if (valueStr == "arbitrating")
value = static_cast<uint8_t>(NodeRole::arbitrating);
else
{
phosphor::logging::log<phosphor::logging::level::ERR>(
"getMultiNodeRole: Invalid dbus value!",
phosphor::logging::entry("VALUE=%s", valueStr.c_str()));
return std::nullopt;
}
return value;
}
catch (const std::exception& e)
{
phosphor::logging::log<phosphor::logging::level::ERR>(
"getMultiNodeRole: can't get multi node role from dbus!",
phosphor::logging::entry("ERR=%s", e.what()));
return std::nullopt;
}
}
ipmi::RspType<uint8_t> ipmiGetMultiNodePresence()
{
std::optional<uint8_t> nodeInfo = getMultiNodeInfo("NodePresence");
if (!nodeInfo)
{
return ipmi::responseResponseError();
}
return ipmi::responseSuccess(*nodeInfo);
}
ipmi::RspType<uint8_t> ipmiGetMultiNodeId()
{
std::optional<uint8_t> nodeInfo = getMultiNodeInfo("NodeId");
if (!nodeInfo)
{
return ipmi::responseResponseError();
}
return ipmi::responseSuccess(*nodeInfo);
}
ipmi::RspType<uint8_t> ipmiGetMultiNodeRole()
{
std::optional<uint8_t> nodeInfo = getMultiNodeRole();
if (!nodeInfo)
{
return ipmi::responseResponseError();
}
return ipmi::responseSuccess(*nodeInfo);
}
void registerMultiNodeFunctions(void)
{
phosphor::logging::log<phosphor::logging::level::INFO>(
"Registering MultiNode commands");
ipmi::registerHandler(ipmi::prioOemBase, ipmi::intel::netFnGeneral,
ipmi::intel::general::cmdGetMultiNodePresence,
ipmi::Privilege::User, ipmiGetMultiNodePresence);
ipmi::registerHandler(ipmi::prioOemBase, ipmi::intel::netFnGeneral,
ipmi::intel::general::cmdGetMultiNodeId,
ipmi::Privilege::User, ipmiGetMultiNodeId);
ipmi::registerHandler(ipmi::prioOemBase, ipmi::intel::netFnGeneral,
ipmi::intel::general::cmdGetMultiNodeRole,
ipmi::Privilege::User, ipmiGetMultiNodeRole);
}
} // namespace ipmi