/** * 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 "profile.hpp" #include "sdbusplus.hpp" #include #include #include #include #include #include namespace phosphor::fan::control::json { using json = nlohmann::json; using namespace phosphor::logging; // String key must be in all lowercase for method lookup const std::map Profile::_methods = { {"all_of", Profile::allOf}}; Profile::Profile(sdbusplus::bus::bus& bus, const json& jsonObj) : ConfigBase(jsonObj), _bus(bus), _active(false) { setActive(jsonObj); } void Profile::setActive(const json& jsonObj) { if (!jsonObj.contains("method") || !jsonObj["method"].contains("name")) { // Log error on missing profile method log("Missing required profile method", entry("JSON=%s", jsonObj.dump().c_str())); throw std::runtime_error("Missing required profile method"); } // The method to use in determining if the profile is active auto method = jsonObj["method"]["name"].get(); std::transform(method.begin(), method.end(), method.begin(), tolower); auto handler = _methods.find(method); if (handler != _methods.end()) { // Call method for determining profile's active state _active = handler->second(jsonObj["method"]); } else { // Construct list of available methods auto methods = std::accumulate( std::next(_methods.begin()), _methods.end(), _methods.begin()->first, [](auto list, auto method) { return std::move(list) + ", " + method.first; }); log("Configured method not available", entry("JSON=%s", jsonObj["method"].dump().c_str()), entry("METHODS_AVAILABLE=%s", methods.c_str())); } } bool Profile::allOf(const json& method) { if (!method.contains("properties")) { log("Missing required all_of method properties list", entry("JSON=%s", method.dump().c_str())); throw std::runtime_error( "Missing required all_of method properties list"); } return std::all_of( method["properties"].begin(), method["properties"].end(), [](const json& obj) { if (!obj.contains("path") || !obj.contains("interface") || !obj.contains("property") || !obj.contains("value")) { log( "Missing required all_of method property parameters", entry("JSON=%s", obj.dump().c_str())); throw std::runtime_error( "Missing required all_of method parameters"); } auto variant = util::SDBusPlus::getPropertyVariant( obj["path"].get(), obj["interface"].get(), obj["property"].get()); return getJsonValue(obj["value"]) == variant; }); } } // namespace phosphor::fan::control::json