diff options
Diffstat (limited to 'agent/sila/software.cpp')
-rw-r--r-- | agent/sila/software.cpp | 225 |
1 files changed, 225 insertions, 0 deletions
diff --git a/agent/sila/software.cpp b/agent/sila/software.cpp new file mode 100644 index 0000000..bed1130 --- /dev/null +++ b/agent/sila/software.cpp @@ -0,0 +1,225 @@ +/** + * @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<uint8_t> + 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<std::string, uint8_t, + uint8_t, uint8_t> +{ + // 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<std::string, uint8_t, uint8_t, + uint8_t>( + 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 <size_t Idx> + void setFieldEnum(const fields_map_t& fields, const char* field, + const phosphor::snmp::data::DBusEnum<uint8_t>& enumcvt) + { + if (fields.find(field) != fields.end() && + std::holds_alternative<std::string>(fields.at(field))) + { + std::get<Idx>(data) = + enumcvt.get(std::get<std::string>(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<FIELD_SOFTWARE_ACTIVATION>(data), + prevPriority = std::get<FIELD_SOFTWARE_PRIORITY>(data); + + setField<FIELD_SOFTWARE_VERSION>(fields, "Version"); + setFieldEnum<FIELD_SOFTWARE_PURPOSE>(fields, "Purpose", purpose); + setFieldEnum<FIELD_SOFTWARE_ACTIVATION>(fields, "Activation", + activation); + setField<FIELD_SOFTWARE_PRIORITY>(fields, "Priority"); + + if (prevActivation != std::get<FIELD_SOFTWARE_ACTIVATION>(data) || + prevPriority != std::get<FIELD_SOFTWARE_PRIORITY>(data)) + { + DEBUGMSGTL(("sila:software", + "Software '%s' version='%s', purpose=%d changed: " + "activation %d -> %d, priority %d -> %d\n", + name.c_str(), + std::get<FIELD_SOFTWARE_VERSION>(data).c_str(), + std::get<FIELD_SOFTWARE_PURPOSE>(data), prevActivation, + std::get<FIELD_SOFTWARE_ACTIVATION>(data), prevPriority, + std::get<FIELD_SOFTWARE_PRIORITY>(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<FIELD_SOFTWARE_VERSION>(data)); + break; + + case COLUMN_SILASOFTWARE_PURPOSE: + VariableList::set(request->requestvb, + std::get<FIELD_SOFTWARE_PURPOSE>(data)); + break; + + case COLUMN_SILASOFTWARE_ACTIVATION: + VariableList::set(request->requestvb, + std::get<FIELD_SOFTWARE_ACTIVATION>(data)); + break; + + case COLUMN_SILASOFTWARE_PRIORITY: + VariableList::set(request->requestvb, + std::get<FIELD_SOFTWARE_PRIORITY>(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<Software> + 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<oid*>(softwareOid), OID_LENGTH(softwareOid)); +} + +} // namespace software +} // namespace sila |