/** * @brief SILA software table implementation. * * This file is part of sila-snmp project. * * Copyright (c) 2022 SILA * * 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 "tracing.hpp" #include "data/table.hpp" #include "data/table/item.hpp" #include "data/enums.hpp" #include "sila/sila_oid.hpp" #include "snmpvars.hpp" #define INVALID_ENUM_VALUE 0xFF namespace sila { namespace software { /** * @brief DBus enum to byte converters. */ const phosphor::snmp::data::DBusEnum purpose = {"xyz.openbmc_project.Software.Version.VersionPurpose", { {"Unknown", 0}, {"Other", 1}, {"System", 2}, {"BMC", 3}, {"Host", 4}, }, INVALID_ENUM_VALUE}, activation = {"xyz.openbmc_project.Software.Activation.Activations", { {"NotReady", 0}, {"Invalid", 1}, {"Ready", 2}, {"Activating", 3}, {"Active", 4}, {"Failed", 5}, }, INVALID_ENUM_VALUE}; /** * @brief Software item implementation. */ struct Software : public phosphor::snmp::data::table::Item { // Indexes of fields in tuple enum Fields { FIELD_SOFTWARE_VERSION = 0, FIELD_SOFTWARE_PURPOSE, FIELD_SOFTWARE_ACTIVATION, FIELD_SOFTWARE_PRIORITY, }; /** * @brief Object constructor. */ Software(const std::string& folder, const std::string& name) : phosphor::snmp::data::table::Item( folder, name, "", // Version INVALID_ENUM_VALUE, // Purpose INVALID_ENUM_VALUE, // Activation INVALID_ENUM_VALUE) // Priority { } /** * @brief Set field value with DBus enum converter. * * @tparam Idx - Index of field * @param fields - DBus fields map * @param field - Name of field in DBus * @param enumcvt - Enum converter */ template void setFieldEnum(const fields_map_t& fields, const char* field, const phosphor::snmp::data::DBusEnum& enumcvt) { if (fields.find(field) != fields.end() && std::holds_alternative(fields.at(field))) { std::get(data) = enumcvt.get(std::get(fields.at(field))); } } /** * @brief Update fields with new values recieved from DBus. */ void setFields(const fields_map_t& fields) override { uint8_t prevActivation = std::get(data), prevPriority = std::get(data); setField(fields, "Version"); setFieldEnum(fields, "Purpose", purpose); setFieldEnum(fields, "Activation", activation); setField(fields, "Priority"); if (prevActivation != std::get(data) || prevPriority != std::get(data)) { DEBUGMSGTL(("sila:software", "Software '%s' version='%s', purpose=%d changed: " "activation %d -> %d, priority %d -> %d\n", name.c_str(), std::get(data).c_str(), std::get(data), prevActivation, std::get(data), prevPriority, std::get(data))); } } enum Columns { COLUMN_SILASOFTWARE_HASH = 1, COLUMN_SILASOFTWARE_VERSION = 2, COLUMN_SILASOFTWARE_PURPOSE = 3, COLUMN_SILASOFTWARE_ACTIVATION = 4, COLUMN_SILASOFTWARE_PRIORITY = 5, }; /** * @brief snmp request handler. */ void get_snmp_reply(netsnmp_agent_request_info* reqinfo, netsnmp_request_info* request) const override { using namespace phosphor::snmp::agent; netsnmp_table_request_info* tinfo = netsnmp_extract_table_info(request); switch (tinfo->colnum) { case COLUMN_SILASOFTWARE_HASH: VariableList::set(request->requestvb, name); break; case COLUMN_SILASOFTWARE_VERSION: VariableList::set(request->requestvb, std::get(data)); break; case COLUMN_SILASOFTWARE_PURPOSE: VariableList::set(request->requestvb, std::get(data)); break; case COLUMN_SILASOFTWARE_ACTIVATION: VariableList::set(request->requestvb, std::get(data)); break; case COLUMN_SILASOFTWARE_PRIORITY: VariableList::set(request->requestvb, std::get(data)); break; default: netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT); break; } } }; constexpr oid softwareOid[] = SILA_OID(5); constexpr auto SOFTWARE_FOLDER = "/xyz/openbmc_project/software"; static phosphor::snmp::data::Table softwareTable("/xyz/openbmc_project/software", { "xyz.openbmc_project.Software.Version", "xyz.openbmc_project.Software.Activation", "xyz.openbmc_project.Software.RedundancyPriority", }); /** * @brief Initialize software table */ void init() { DEBUGMSGTL(("sila:init", "Initialize silaSoftwareTable\n")); softwareTable.update(); softwareTable.init_mib("silaSoftwareTable", softwareOid, OID_LENGTH(softwareOid), Software::COLUMN_SILASOFTWARE_HASH, Software::COLUMN_SILASOFTWARE_PRIORITY); } /** * @brief Deinitialize software table */ void destroy() { DEBUGMSGTL(("sila:shutdown", "Deinitialize silaSoftwareTable\n")); unregister_mib(const_cast(softwareOid), OID_LENGTH(softwareOid)); } } // namespace software } // namespace sila