1 /* 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 */ 16 /// \file entity_manager.hpp 17 18 #pragma once 19 20 #include "utils.hpp" 21 22 #include <systemd/sd-journal.h> 23 24 #include <boost/container/flat_map.hpp> 25 #include <nlohmann/json.hpp> 26 #include <sdbusplus/asio/object_server.hpp> 27 28 #include <iostream> 29 #include <list> 30 #include <optional> 31 #include <string> 32 33 struct DBusDeviceDescriptor 34 { 35 DBusInterface interface; 36 std::string path; 37 }; 38 39 using FoundDevices = std::vector<DBusDeviceDescriptor>; 40 41 struct 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 50 enum class probe_type_codes 51 { 52 FALSE_T, 53 TRUE_T, 54 AND, 55 OR, 56 FOUND, 57 MATCH_ONE 58 }; 59 60 using FoundProbeTypeT = 61 std::optional<boost::container::flat_map<const char*, probe_type_codes, 62 CmpStr>::const_iterator>; 63 FoundProbeTypeT findProbeType(const std::string& probe); 64 65 struct PerformScan : std::enable_shared_from_this<PerformScan> 66 { 67 68 PerformScan(nlohmann::json& systemConfiguration, 69 nlohmann::json& missingConfigurations, 70 std::list<nlohmann::json>& configurations, 71 sdbusplus::asio::object_server& objServer, 72 std::function<void()>&& callback); 73 void updateSystemConfiguration(const nlohmann::json& recordRef, 74 const std::string& probeName, 75 FoundDevices& foundDevices); 76 void run(void); 77 virtual ~PerformScan(); 78 nlohmann::json& _systemConfiguration; 79 nlohmann::json& _missingConfigurations; 80 std::list<nlohmann::json> _configurations; 81 sdbusplus::asio::object_server& objServer; 82 std::function<void()> _callback; 83 bool _passed = false; 84 MapperGetSubTreeResponse dbusProbeObjects; 85 std::vector<std::string> passedProbes; 86 }; 87 88 // this class finds the needed dbus fields and on destruction runs the probe 89 struct PerformProbe : std::enable_shared_from_this<PerformProbe> 90 { 91 PerformProbe(nlohmann::json& recordRef, 92 const std::vector<std::string>& probeCommand, 93 std::string probeName, std::shared_ptr<PerformScan>& scanPtr); 94 virtual ~PerformProbe(); 95 96 nlohmann::json& recordRef; 97 std::vector<std::string> _probeCommand; 98 std::string probeName; 99 std::shared_ptr<PerformScan> scan; 100 }; 101 102 inline void logDeviceAdded(const nlohmann::json& record) 103 { 104 105 if (!deviceHasLogging(record)) 106 { 107 return; 108 } 109 auto findType = record.find("Type"); 110 auto findAsset = 111 record.find("xyz.openbmc_project.Inventory.Decorator.Asset"); 112 113 std::string model = "Unknown"; 114 std::string type = "Unknown"; 115 std::string sn = "Unknown"; 116 std::string name = "Unknown"; 117 118 if (findType != record.end()) 119 { 120 type = findType->get<std::string>(); 121 } 122 if (findAsset != record.end()) 123 { 124 auto findModel = findAsset->find("Model"); 125 auto findSn = findAsset->find("SerialNumber"); 126 if (findModel != findAsset->end()) 127 { 128 model = findModel->get<std::string>(); 129 } 130 if (findSn != findAsset->end()) 131 { 132 const std::string* getSn = findSn->get_ptr<const std::string*>(); 133 if (getSn != nullptr) 134 { 135 sn = *getSn; 136 } 137 else 138 { 139 sn = findSn->dump(); 140 } 141 } 142 } 143 144 auto findName = record.find("Name"); 145 if (findName != record.end()) 146 { 147 name = findName->get<std::string>(); 148 } 149 150 sd_journal_send("MESSAGE=Inventory Added: %s", name.c_str(), "PRIORITY=%i", 151 LOG_INFO, "REDFISH_MESSAGE_ID=%s", 152 "OpenBMC.0.1.InventoryAdded", 153 "REDFISH_MESSAGE_ARGS=%s,%s,%s", model.c_str(), 154 type.c_str(), sn.c_str(), "NAME=%s", name.c_str(), NULL); 155 } 156 157 inline void logDeviceRemoved(const nlohmann::json& record) 158 { 159 if (!deviceHasLogging(record)) 160 { 161 return; 162 } 163 auto findType = record.find("Type"); 164 auto findAsset = 165 record.find("xyz.openbmc_project.Inventory.Decorator.Asset"); 166 167 std::string model = "Unknown"; 168 std::string type = "Unknown"; 169 std::string sn = "Unknown"; 170 std::string name = "Unknown"; 171 172 if (findType != record.end()) 173 { 174 type = findType->get<std::string>(); 175 } 176 if (findAsset != record.end()) 177 { 178 auto findModel = findAsset->find("Model"); 179 auto findSn = findAsset->find("SerialNumber"); 180 if (findModel != findAsset->end()) 181 { 182 model = findModel->get<std::string>(); 183 } 184 if (findSn != findAsset->end()) 185 { 186 const std::string* getSn = findSn->get_ptr<const std::string*>(); 187 if (getSn != nullptr) 188 { 189 sn = *getSn; 190 } 191 else 192 { 193 sn = findSn->dump(); 194 } 195 } 196 } 197 198 auto findName = record.find("Name"); 199 if (findName != record.end()) 200 { 201 name = findName->get<std::string>(); 202 } 203 204 sd_journal_send("MESSAGE=Inventory Removed: %s", name.c_str(), 205 "PRIORITY=%i", LOG_INFO, "REDFISH_MESSAGE_ID=%s", 206 "OpenBMC.0.1.InventoryRemoved", 207 "REDFISH_MESSAGE_ARGS=%s,%s,%s", model.c_str(), 208 type.c_str(), sn.c_str(), "NAME=%s", name.c_str(), NULL); 209 } 210