blob: 5b5bbf6d72f721fb663dfdcb1594a9f95cf88a84 [file] [log] [blame]
James Feist1df06a42019-04-11 14:23:04 -07001/*
2// Copyright (c) 2018 Intel Corporation
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15*/
Brad Bishope45d8c72022-05-25 15:12:53 -040016/// \file entity_manager.hpp
James Feist1df06a42019-04-11 14:23:04 -070017
18#pragma once
19
Christopher Meisfc9e7fd2025-04-03 13:13:35 +020020#include "../utils.hpp"
Alexander Hansen57604ed2025-06-27 13:22:28 +020021#include "dbus_interface.hpp"
Christopher Meiscf6a75b2025-06-03 07:53:50 +020022#include "topology.hpp"
James Feist733f7652019-11-13 14:32:29 -080023
James Feist1df06a42019-04-11 14:23:04 -070024#include <systemd/sd-journal.h>
25
James Feist733f7652019-11-13 14:32:29 -080026#include <boost/container/flat_map.hpp>
James Feist1a996582019-05-14 15:10:06 -070027#include <nlohmann/json.hpp>
Christopher Meiscf6a75b2025-06-03 07:53:50 +020028#include <sdbusplus/asio/connection.hpp>
James Feist4dc617b2020-05-01 09:54:47 -070029#include <sdbusplus/asio/object_server.hpp>
James Feist8c505da2020-05-28 10:06:33 -070030
James Feist1df06a42019-04-11 14:23:04 -070031#include <string>
32
Christopher Meiscf6a75b2025-06-03 07:53:50 +020033class EntityManager
34{
35 public:
36 explicit EntityManager(
Alexander Hansena555acf2025-06-27 11:59:10 +020037 std::shared_ptr<sdbusplus::asio::connection>& systemBus,
38 boost::asio::io_context& io);
Christopher Meiscf6a75b2025-06-03 07:53:50 +020039
40 std::shared_ptr<sdbusplus::asio::connection> systemBus;
41 sdbusplus::asio::object_server objServer;
42 std::shared_ptr<sdbusplus::asio::dbus_interface> entityIface;
43 nlohmann::json lastJson;
44 nlohmann::json systemConfiguration;
45 Topology topology;
Alexander Hansena555acf2025-06-27 11:59:10 +020046 boost::asio::io_context& io;
Christopher Meiscf6a75b2025-06-03 07:53:50 +020047
Alexander Hansen57604ed2025-06-27 13:22:28 +020048 dbus_interface::EMDBusInterface dbus_interface;
49
Christopher Meiscf6a75b2025-06-03 07:53:50 +020050 void propertiesChangedCallback();
51 void registerCallback(const std::string& path);
52 void publishNewConfiguration(const size_t& instance, size_t count,
53 boost::asio::steady_timer& timer,
54 nlohmann::json newConfiguration);
55 void postToDbus(const nlohmann::json& newConfiguration);
56 void pruneConfiguration(bool powerOff, const std::string& name,
57 const nlohmann::json& device);
58
59 void initFilters(const std::set<std::string>& probeInterfaces);
Alexander Hansenad28e402025-06-25 12:38:20 +020060
61 void handleCurrentConfigurationJson();
Alexander Hansen0f7bd782025-06-27 13:39:53 +020062
63 private:
64 std::unique_ptr<sdbusplus::bus::match_t> nameOwnerChangedMatch = nullptr;
65 std::unique_ptr<sdbusplus::bus::match_t> interfacesAddedMatch = nullptr;
66 std::unique_ptr<sdbusplus::bus::match_t> interfacesRemovedMatch = nullptr;
Alexander Hansen95ab18f2025-06-27 13:58:10 +020067
68 bool scannedPowerOff = false;
69 bool scannedPowerOn = false;
70
Alexander Hansen16d40022025-06-27 14:22:56 +020071 bool propertiesChangedInProgress = false;
Alexander Hansenb1340da2025-06-27 14:29:13 +020072 boost::asio::steady_timer propertiesChangedTimer;
Alexander Hansen16d40022025-06-27 14:22:56 +020073
Alexander Hansen95ab18f2025-06-27 13:58:10 +020074 void startRemovedTimer(boost::asio::steady_timer& timer,
75 nlohmann::json& systemConfiguration);
Christopher Meiscf6a75b2025-06-03 07:53:50 +020076};
77
James Feist1a996582019-05-14 15:10:06 -070078inline void logDeviceAdded(const nlohmann::json& record)
James Feist1df06a42019-04-11 14:23:04 -070079{
James Feist1ffa4a42020-04-22 18:27:17 -070080 if (!deviceHasLogging(record))
81 {
82 return;
83 }
James Feist1a996582019-05-14 15:10:06 -070084 auto findType = record.find("Type");
85 auto findAsset =
86 record.find("xyz.openbmc_project.Inventory.Decorator.Asset");
87
Konstantin Aladysheve7ac9c92021-09-10 09:20:17 +030088 std::string model = "Unknown";
James Feist1a996582019-05-14 15:10:06 -070089 std::string type = "Unknown";
Konstantin Aladysheve7ac9c92021-09-10 09:20:17 +030090 std::string sn = "Unknown";
Matt Spinler200bf402022-08-04 09:14:18 -050091 std::string name = "Unknown";
James Feist1a996582019-05-14 15:10:06 -070092
93 if (findType != record.end())
94 {
95 type = findType->get<std::string>();
96 }
97 if (findAsset != record.end())
98 {
99 auto findModel = findAsset->find("Model");
100 auto findSn = findAsset->find("SerialNumber");
101 if (findModel != findAsset->end())
102 {
103 model = findModel->get<std::string>();
104 }
105 if (findSn != findAsset->end())
106 {
James Feistf5125b02019-06-06 11:27:43 -0700107 const std::string* getSn = findSn->get_ptr<const std::string*>();
108 if (getSn != nullptr)
109 {
110 sn = *getSn;
111 }
112 else
113 {
114 sn = findSn->dump();
115 }
James Feist1a996582019-05-14 15:10:06 -0700116 }
117 }
118
Matt Spinler200bf402022-08-04 09:14:18 -0500119 auto findName = record.find("Name");
120 if (findName != record.end())
121 {
122 name = findName->get<std::string>();
123 }
124
125 sd_journal_send("MESSAGE=Inventory Added: %s", name.c_str(), "PRIORITY=%i",
126 LOG_INFO, "REDFISH_MESSAGE_ID=%s",
127 "OpenBMC.0.1.InventoryAdded",
James Feist1a996582019-05-14 15:10:06 -0700128 "REDFISH_MESSAGE_ARGS=%s,%s,%s", model.c_str(),
Matt Spinler200bf402022-08-04 09:14:18 -0500129 type.c_str(), sn.c_str(), "NAME=%s", name.c_str(), NULL);
James Feist1df06a42019-04-11 14:23:04 -0700130}
131
James Feist1a996582019-05-14 15:10:06 -0700132inline void logDeviceRemoved(const nlohmann::json& record)
James Feist1df06a42019-04-11 14:23:04 -0700133{
James Feist1ffa4a42020-04-22 18:27:17 -0700134 if (!deviceHasLogging(record))
135 {
136 return;
137 }
James Feist1a996582019-05-14 15:10:06 -0700138 auto findType = record.find("Type");
139 auto findAsset =
140 record.find("xyz.openbmc_project.Inventory.Decorator.Asset");
141
Konstantin Aladysheve7ac9c92021-09-10 09:20:17 +0300142 std::string model = "Unknown";
James Feist1a996582019-05-14 15:10:06 -0700143 std::string type = "Unknown";
Konstantin Aladysheve7ac9c92021-09-10 09:20:17 +0300144 std::string sn = "Unknown";
Matt Spinler200bf402022-08-04 09:14:18 -0500145 std::string name = "Unknown";
James Feist1a996582019-05-14 15:10:06 -0700146
147 if (findType != record.end())
148 {
149 type = findType->get<std::string>();
150 }
151 if (findAsset != record.end())
152 {
153 auto findModel = findAsset->find("Model");
154 auto findSn = findAsset->find("SerialNumber");
155 if (findModel != findAsset->end())
156 {
157 model = findModel->get<std::string>();
158 }
159 if (findSn != findAsset->end())
160 {
James Feistf5125b02019-06-06 11:27:43 -0700161 const std::string* getSn = findSn->get_ptr<const std::string*>();
162 if (getSn != nullptr)
163 {
164 sn = *getSn;
165 }
166 else
167 {
168 sn = findSn->dump();
169 }
James Feist1a996582019-05-14 15:10:06 -0700170 }
171 }
James Feist1df06a42019-04-11 14:23:04 -0700172
Matt Spinler200bf402022-08-04 09:14:18 -0500173 auto findName = record.find("Name");
174 if (findName != record.end())
175 {
176 name = findName->get<std::string>();
177 }
178
179 sd_journal_send("MESSAGE=Inventory Removed: %s", name.c_str(),
180 "PRIORITY=%i", LOG_INFO, "REDFISH_MESSAGE_ID=%s",
181 "OpenBMC.0.1.InventoryRemoved",
James Feist1a996582019-05-14 15:10:06 -0700182 "REDFISH_MESSAGE_ARGS=%s,%s,%s", model.c_str(),
Matt Spinler200bf402022-08-04 09:14:18 -0500183 type.c_str(), sn.c_str(), "NAME=%s", name.c_str(), NULL);
James Feist4dc617b2020-05-01 09:54:47 -0700184}