diff options
Diffstat (limited to 'agent/sila/inventory.cpp')
-rw-r--r-- | agent/sila/inventory.cpp | 249 |
1 files changed, 249 insertions, 0 deletions
diff --git a/agent/sila/inventory.cpp b/agent/sila/inventory.cpp new file mode 100644 index 0000000..233b8f8 --- /dev/null +++ b/agent/sila/inventory.cpp @@ -0,0 +1,249 @@ +/** + * @brief SILA inventory 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 "sila/sila_oid.hpp" +#include "snmptrap.hpp" + +namespace sila +{ +namespace inventory +{ +using OID = phosphor::snmp::agent::OID; +static const OID NOTIFY_OID = SILA_OID(0, 7); + +struct InventoryItem : public phosphor::snmp::data::table::Item< + std::string, std::string, std::string, std::string, + std::string, std::string, std::string, bool, bool> +{ + // Indexes of fields in tuble + enum Fields + { + FIELD_INVENTORY_PRETTY_NAME = 0, + FIELD_INVENTORY_MANUFACTURER, + FIELD_INVENTORY_BUILD_DATE, + FIELD_INVENTORY_MODEL, + FIELD_INVENTORY_PART_NUMBER, + FIELD_INVENTORY_SERIAL_NUMBER, + FIELD_INVENTORY_VERSION, + FIELD_INVENTORY_PRESENT, + FIELD_INVENTORY_FUNCTIONAL, + }; + + enum Columns + { + COLUMN_SILAINVENTORY_PATH = 1, + COLUMN_SILAINVENTORY_NAME, + COLUMN_SILAINVENTORY_MANUFACTURER, + COLUMN_SILAINVENTORY_BUILD_DATE, + COLUMN_SILAINVENTORY_MODEL, + COLUMN_SILAINVENTORY_PART_NUMBER, + COLUMN_SILAINVENTORY_SERIAL_NUMBER, + COLUMN_SILAINVENTORY_VERSION, + COLUMN_SILAINVENTORY_PRESENT, + COLUMN_SILAINVENTORY_FUNCTIONAL, + }; + + InventoryItem(const std::string& folder, const std::string& name) : + phosphor::snmp::data::table::Item<std::string, std::string, std::string, + std::string, std::string, std::string, + std::string, bool, bool>( + folder, name, + "", // Pretty Name + "", // Manufacturer + "", // Build date + "", // Model + "", // Part number + "", // Serial number + "", // Version + false, // Present + false) // Functional + { + phosphor::snmp::agent::make_oid( + _presentOid, ".1.3.6.1.4.1.49769.4.1.%lu.\"%s\"", + COLUMN_SILAINVENTORY_PRESENT, name.c_str()); + phosphor::snmp::agent::make_oid( + _functionalOid, ".1.3.6.1.4.1.49769.4.1.%lu.\"%s\"", + COLUMN_SILAINVENTORY_FUNCTIONAL, name.c_str()); + } + + void setFields(const fields_map_t& fields) override + { + bool isPresent = std::get<FIELD_INVENTORY_PRESENT>(data); + bool isFunctional = std::get<FIELD_INVENTORY_FUNCTIONAL>(data); + + setField<FIELD_INVENTORY_PRETTY_NAME>(fields, "PrettyName"); + setField<FIELD_INVENTORY_MANUFACTURER>(fields, "Manufacturer"); + setField<FIELD_INVENTORY_BUILD_DATE>(fields, "BuildDate"); + setField<FIELD_INVENTORY_MODEL>(fields, "Model"); + setField<FIELD_INVENTORY_PART_NUMBER>(fields, "PartNumber"); + setField<FIELD_INVENTORY_SERIAL_NUMBER>(fields, "SerialNumber"); + setField<FIELD_INVENTORY_VERSION>(fields, "Version"); + setField<FIELD_INVENTORY_PRESENT>(fields, "Present"); + setField<FIELD_INVENTORY_FUNCTIONAL>(fields, "Functional"); + + if (isPresent != std::get<FIELD_INVENTORY_PRESENT>(data) || + isFunctional != std::get<FIELD_INVENTORY_FUNCTIONAL>(data)) + { + DEBUGMSGTL(("sila:inventory", + "Inventory item '%s' at '%s': " + "present %d -> %d, function %d -> %d\n", + std::get<FIELD_INVENTORY_PRETTY_NAME>(data).c_str(), + name.c_str(), isPresent, + std::get<FIELD_INVENTORY_PRESENT>(data), isFunctional, + std::get<FIELD_INVENTORY_FUNCTIONAL>(data))); + + phosphor::snmp::agent::Trap trap(NOTIFY_OID); + trap.add_field(_presentOid, + std::get<FIELD_INVENTORY_PRESENT>(data)); + trap.add_field(_functionalOid, + std::get<FIELD_INVENTORY_FUNCTIONAL>(data)); + trap.send(); + } + } + + 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_SILAINVENTORY_PATH: + VariableList::set(request->requestvb, name); + break; + + case COLUMN_SILAINVENTORY_NAME: + VariableList::set(request->requestvb, + std::get<FIELD_INVENTORY_PRETTY_NAME>(data)); + break; + + case COLUMN_SILAINVENTORY_MANUFACTURER: + VariableList::set(request->requestvb, + std::get<FIELD_INVENTORY_MANUFACTURER>(data)); + break; + + case COLUMN_SILAINVENTORY_BUILD_DATE: + VariableList::set(request->requestvb, + std::get<FIELD_INVENTORY_BUILD_DATE>(data)); + break; + + case COLUMN_SILAINVENTORY_MODEL: + VariableList::set(request->requestvb, + std::get<FIELD_INVENTORY_MODEL>(data)); + break; + + case COLUMN_SILAINVENTORY_PART_NUMBER: + VariableList::set(request->requestvb, + std::get<FIELD_INVENTORY_PART_NUMBER>(data)); + break; + + case COLUMN_SILAINVENTORY_SERIAL_NUMBER: + VariableList::set( + request->requestvb, + std::get<FIELD_INVENTORY_SERIAL_NUMBER>(data)); + break; + + case COLUMN_SILAINVENTORY_VERSION: + VariableList::set(request->requestvb, + std::get<FIELD_INVENTORY_VERSION>(data)); + break; + + case COLUMN_SILAINVENTORY_PRESENT: + VariableList::set(request->requestvb, + std::get<FIELD_INVENTORY_PRESENT>(data)); + break; + + case COLUMN_SILAINVENTORY_FUNCTIONAL: + VariableList::set(request->requestvb, + std::get<FIELD_INVENTORY_FUNCTIONAL>(data)); + break; + + default: + netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT); + break; + } + } + + void onCreate() override + { + DEBUGMSGTL( + ("sila:inventory", "Inventory item '%s' added.\n", name.c_str())); + } + + void onDestroy() override + { + DEBUGMSGTL(("sila:inventory", "Inventory item '%s' removed.\n", + name.c_str())); + if (std::get<FIELD_INVENTORY_PRESENT>(data) || + std::get<FIELD_INVENTORY_FUNCTIONAL>(data)) + { + phosphor::snmp::agent::Trap trap(NOTIFY_OID); + trap.add_field(_presentOid, false); + trap.add_field(_functionalOid, false); + trap.send(); + } + } + + OID _presentOid; + OID _functionalOid; +}; + +static phosphor::snmp::agent::OID inventoryTableOid = SILA_OID(4); + +static phosphor::snmp::data::Table<InventoryItem> + inventoryTable("/xyz/openbmc_project/inventory", + { + "xyz.openbmc_project.Inventory.Item", + "xyz.openbmc_project.Inventory.Decorator.Asset", + "xyz.openbmc_project.Inventory.Decorator.Revision", + "xyz.openbmc_project.State.Decorator.OperationalStatus", + }); + +/** + * @brief Initialize inventory table + */ +void init() +{ + DEBUGMSGTL(("sila:init", "Initialize silaInventoryTable\n")); + + inventoryTable.update(); + inventoryTable.init_mib("silaInventoryTable", inventoryTableOid.data(), + inventoryTableOid.size(), + InventoryItem::COLUMN_SILAINVENTORY_PATH, + InventoryItem::COLUMN_SILAINVENTORY_FUNCTIONAL); +} + +/** + * @brief Deinitialize inventory table + */ +void destroy() +{ + DEBUGMSGTL(("sila:shutdown", "Deinitialize silaInventoryTable\n")); + unregister_mib(inventoryTableOid.data(), inventoryTableOid.size()); +} + +} // namespace inventory +} // namespace sila |