blob: 0fbef7964fa714b8dfe0c92eec3b119cca8303ec [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
Brad Bishope45d8c72022-05-25 15:12:53 -040020#include "utils.hpp"
James Feist733f7652019-11-13 14:32:29 -080021
James Feist1df06a42019-04-11 14:23:04 -070022#include <systemd/sd-journal.h>
23
James Feist733f7652019-11-13 14:32:29 -080024#include <boost/container/flat_map.hpp>
James Feist1a996582019-05-14 15:10:06 -070025#include <nlohmann/json.hpp>
James Feist4dc617b2020-05-01 09:54:47 -070026#include <sdbusplus/asio/object_server.hpp>
James Feist8c505da2020-05-28 10:06:33 -070027
28#include <iostream>
29#include <list>
Andrew Jeffery666583b2021-12-01 15:50:12 +103030#include <optional>
James Feist1df06a42019-04-11 14:23:04 -070031#include <string>
32
Andrew Jefferyf5772d22022-04-12 22:05:30 +093033struct DBusDeviceDescriptor
34{
35 DBusInterface interface;
36 std::string path;
37};
38
39using FoundDevices = std::vector<DBusDeviceDescriptor>;
James Feist7d807752019-11-13 14:47:57 -080040
Andrew Jeffery47af65a2021-12-01 14:16:31 +103041struct CmpStr
42{
43 bool operator()(const char* a, const char* b) const
44 {
45 return std::strcmp(a, b) < 0;
46 }
47};
48
49// underscore T for collison with dbus c api
50enum class probe_type_codes
51{
52 FALSE_T,
53 TRUE_T,
54 AND,
55 OR,
56 FOUND,
57 MATCH_ONE
58};
59
Andrew Jeffery666583b2021-12-01 15:50:12 +103060using FoundProbeTypeT =
61 std::optional<boost::container::flat_map<const char*, probe_type_codes,
62 CmpStr>::const_iterator>;
63FoundProbeTypeT findProbeType(const std::string& probe);
64
James Feist733f7652019-11-13 14:32:29 -080065struct PerformScan : std::enable_shared_from_this<PerformScan>
66{
James Feist733f7652019-11-13 14:32:29 -080067 PerformScan(nlohmann::json& systemConfiguration,
68 nlohmann::json& missingConfigurations,
69 std::list<nlohmann::json>& configurations,
James Feist4dc617b2020-05-01 09:54:47 -070070 sdbusplus::asio::object_server& objServer,
71 std::function<void()>&& callback);
Andrew Jefferyae6c1a42022-04-19 15:44:42 +093072 void updateSystemConfiguration(const nlohmann::json& recordRef,
73 const std::string& probeName,
Andrew Jefferyaf9b46b2022-04-21 12:34:43 +093074 FoundDevices& foundDevices);
Delphine CC Chiua3ca14a2024-03-27 17:02:24 +080075 void run();
James Feist733f7652019-11-13 14:32:29 -080076 virtual ~PerformScan();
77 nlohmann::json& _systemConfiguration;
78 nlohmann::json& _missingConfigurations;
79 std::list<nlohmann::json> _configurations;
James Feist4dc617b2020-05-01 09:54:47 -070080 sdbusplus::asio::object_server& objServer;
81 std::function<void()> _callback;
James Feist733f7652019-11-13 14:32:29 -080082 bool _passed = false;
Andrew Jefferyac20bd92022-04-05 11:11:40 +093083 MapperGetSubTreeResponse dbusProbeObjects;
James Feist733f7652019-11-13 14:32:29 -080084 std::vector<std::string> passedProbes;
85};
86
James Feist7d807752019-11-13 14:47:57 -080087// this class finds the needed dbus fields and on destruction runs the probe
88struct PerformProbe : std::enable_shared_from_this<PerformProbe>
89{
Andrew Jefferyea4ff022022-04-21 12:31:40 +093090 PerformProbe(nlohmann::json& recordRef,
91 const std::vector<std::string>& probeCommand,
92 std::string probeName, std::shared_ptr<PerformScan>& scanPtr);
James Feist7d807752019-11-13 14:47:57 -080093 virtual ~PerformProbe();
94
Andrew Jefferyea4ff022022-04-21 12:31:40 +093095 nlohmann::json& recordRef;
James Feist7d807752019-11-13 14:47:57 -080096 std::vector<std::string> _probeCommand;
Andrew Jefferyea4ff022022-04-21 12:31:40 +093097 std::string probeName;
James Feist7d807752019-11-13 14:47:57 -080098 std::shared_ptr<PerformScan> scan;
James Feist7d807752019-11-13 14:47:57 -080099};
100
James Feist1a996582019-05-14 15:10:06 -0700101inline void logDeviceAdded(const nlohmann::json& record)
James Feist1df06a42019-04-11 14:23:04 -0700102{
James Feist1ffa4a42020-04-22 18:27:17 -0700103 if (!deviceHasLogging(record))
104 {
105 return;
106 }
James Feist1a996582019-05-14 15:10:06 -0700107 auto findType = record.find("Type");
108 auto findAsset =
109 record.find("xyz.openbmc_project.Inventory.Decorator.Asset");
110
Konstantin Aladysheve7ac9c92021-09-10 09:20:17 +0300111 std::string model = "Unknown";
James Feist1a996582019-05-14 15:10:06 -0700112 std::string type = "Unknown";
Konstantin Aladysheve7ac9c92021-09-10 09:20:17 +0300113 std::string sn = "Unknown";
Matt Spinler200bf402022-08-04 09:14:18 -0500114 std::string name = "Unknown";
James Feist1a996582019-05-14 15:10:06 -0700115
116 if (findType != record.end())
117 {
118 type = findType->get<std::string>();
119 }
120 if (findAsset != record.end())
121 {
122 auto findModel = findAsset->find("Model");
123 auto findSn = findAsset->find("SerialNumber");
124 if (findModel != findAsset->end())
125 {
126 model = findModel->get<std::string>();
127 }
128 if (findSn != findAsset->end())
129 {
James Feistf5125b02019-06-06 11:27:43 -0700130 const std::string* getSn = findSn->get_ptr<const std::string*>();
131 if (getSn != nullptr)
132 {
133 sn = *getSn;
134 }
135 else
136 {
137 sn = findSn->dump();
138 }
James Feist1a996582019-05-14 15:10:06 -0700139 }
140 }
141
Matt Spinler200bf402022-08-04 09:14:18 -0500142 auto findName = record.find("Name");
143 if (findName != record.end())
144 {
145 name = findName->get<std::string>();
146 }
147
148 sd_journal_send("MESSAGE=Inventory Added: %s", name.c_str(), "PRIORITY=%i",
149 LOG_INFO, "REDFISH_MESSAGE_ID=%s",
150 "OpenBMC.0.1.InventoryAdded",
James Feist1a996582019-05-14 15:10:06 -0700151 "REDFISH_MESSAGE_ARGS=%s,%s,%s", model.c_str(),
Matt Spinler200bf402022-08-04 09:14:18 -0500152 type.c_str(), sn.c_str(), "NAME=%s", name.c_str(), NULL);
James Feist1df06a42019-04-11 14:23:04 -0700153}
154
James Feist1a996582019-05-14 15:10:06 -0700155inline void logDeviceRemoved(const nlohmann::json& record)
James Feist1df06a42019-04-11 14:23:04 -0700156{
James Feist1ffa4a42020-04-22 18:27:17 -0700157 if (!deviceHasLogging(record))
158 {
159 return;
160 }
James Feist1a996582019-05-14 15:10:06 -0700161 auto findType = record.find("Type");
162 auto findAsset =
163 record.find("xyz.openbmc_project.Inventory.Decorator.Asset");
164
Konstantin Aladysheve7ac9c92021-09-10 09:20:17 +0300165 std::string model = "Unknown";
James Feist1a996582019-05-14 15:10:06 -0700166 std::string type = "Unknown";
Konstantin Aladysheve7ac9c92021-09-10 09:20:17 +0300167 std::string sn = "Unknown";
Matt Spinler200bf402022-08-04 09:14:18 -0500168 std::string name = "Unknown";
James Feist1a996582019-05-14 15:10:06 -0700169
170 if (findType != record.end())
171 {
172 type = findType->get<std::string>();
173 }
174 if (findAsset != record.end())
175 {
176 auto findModel = findAsset->find("Model");
177 auto findSn = findAsset->find("SerialNumber");
178 if (findModel != findAsset->end())
179 {
180 model = findModel->get<std::string>();
181 }
182 if (findSn != findAsset->end())
183 {
James Feistf5125b02019-06-06 11:27:43 -0700184 const std::string* getSn = findSn->get_ptr<const std::string*>();
185 if (getSn != nullptr)
186 {
187 sn = *getSn;
188 }
189 else
190 {
191 sn = findSn->dump();
192 }
James Feist1a996582019-05-14 15:10:06 -0700193 }
194 }
James Feist1df06a42019-04-11 14:23:04 -0700195
Matt Spinler200bf402022-08-04 09:14:18 -0500196 auto findName = record.find("Name");
197 if (findName != record.end())
198 {
199 name = findName->get<std::string>();
200 }
201
202 sd_journal_send("MESSAGE=Inventory Removed: %s", name.c_str(),
203 "PRIORITY=%i", LOG_INFO, "REDFISH_MESSAGE_ID=%s",
204 "OpenBMC.0.1.InventoryRemoved",
James Feist1a996582019-05-14 15:10:06 -0700205 "REDFISH_MESSAGE_ARGS=%s,%s,%s", model.c_str(),
Matt Spinler200bf402022-08-04 09:14:18 -0500206 type.c_str(), sn.c_str(), "NAME=%s", name.c_str(), NULL);
James Feist4dc617b2020-05-01 09:54:47 -0700207}