blob: 0cee70a02346a79eb0a53127e7f4a14eef4e0433 [file] [log] [blame]
/**
* Copyright © 2020 IBM 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 "internal_interface.hpp"
#include <sdbusplus/message.hpp>
#include <algorithm>
#include <iterator>
#include <numeric>
namespace phosphor
{
namespace led
{
namespace sysfs
{
namespace interface
{
InternalInterface::InternalInterface(sdbusplus::bus_t& bus, const char* path) :
bus(bus), serverInterface(bus, path, internalInterface, vtable.data(), this)
{}
std::string InternalInterface::getDbusName(const LedDescr& ledDescr)
{
std::vector<std::string> words;
if (ledDescr.devicename.has_value())
{
words.emplace_back(ledDescr.devicename.value());
}
if (ledDescr.function.has_value())
{
words.emplace_back(ledDescr.function.value());
}
if (ledDescr.color.has_value())
{
words.emplace_back(ledDescr.color.value());
}
std::string s =
std::accumulate(std::next(words.begin()), words.end(), words[0],
[](std::string a, const std::string& b) {
return std::move(a) + "_" + b;
});
// we assume the string to be a correct dbus name besides
// this detail
std::replace(s.begin(), s.end(), '-', '_');
return s;
}
void InternalInterface::createLEDPath(const std::string& ledName)
{
std::string name;
std::string path = devParent + ledName;
if (!std::filesystem::exists(fs::path(path)))
{
lg2::error("No such directory {PATH}", "PATH", path);
return;
}
auto sled = std::make_unique<phosphor::led::SysfsLed>(fs::path(path));
// Convert LED name in sysfs into DBus name
const LedDescr ledDescr = sled->getLedDescr();
name = getDbusName(ledDescr);
lg2::debug("LED {NAME} receives dbus name {DBUSNAME}", "NAME", ledName,
"DBUSNAME", name);
// Unique path name representing a single LED.
std::string objPath = std::string(physParent) + "/" + name;
if (leds.contains(objPath))
{
return;
}
leds.emplace(objPath, std::make_unique<phosphor::led::Physical>(
bus, objPath, std::move(sled),
ledDescr.color.value_or("")));
}
void InternalInterface::addLED(const std::string& name)
{
createLEDPath(name);
}
// NOLINTNEXTLINE(readability-convert-member-functions-to-static)
void InternalInterface::removeLED(const std::string& name)
{
lg2::debug("RemoveLED is not configured {NAME}", "NAME", name);
}
int InternalInterface::addLedConfigure(sd_bus_message* msg, void* context,
sd_bus_error* error)
{
if (msg == nullptr && context == nullptr)
{
lg2::error("Unable to configure addLed");
return -EINVAL;
}
try
{
auto message = sdbusplus::message_t(msg);
auto ledName = message.unpack<std::string>();
auto* self = static_cast<InternalInterface*>(context);
self->addLED(ledName);
auto reply = message.new_method_return();
reply.method_return();
}
catch (const sdbusplus::exception_t& e)
{
return sd_bus_error_set(error, e.name(), e.description());
}
return 1;
}
int InternalInterface::removeLedConfigure(sd_bus_message* msg, void* context,
sd_bus_error* error)
{
if (msg == nullptr && context == nullptr)
{
lg2::error("Unable to configure removeLed");
return -EINVAL;
}
try
{
auto message = sdbusplus::message_t(msg);
auto ledName = message.unpack<std::string>();
auto* self = static_cast<InternalInterface*>(context);
self->removeLED(ledName);
auto reply = message.new_method_return();
reply.method_return();
}
catch (const sdbusplus::exception_t& e)
{
return sd_bus_error_set(error, e.name(), e.description());
}
return 1;
}
const std::array<sdbusplus::vtable::vtable_t, 4> InternalInterface::vtable = {
sdbusplus::vtable::start(),
// AddLed method takes a string parameter and returns void
sdbusplus::vtable::method("AddLED", "s", "", addLedConfigure),
// RemoveLed method takes a string parameter and returns void
sdbusplus::vtable::method("RemoveLED", "s", "", removeLedConfigure),
sdbusplus::vtable::end()};
} // namespace interface
} // namespace sysfs
} // namespace led
} // namespace phosphor