1e0017ebbSMatt Spinler /** 2e0017ebbSMatt Spinler * Copyright © 2018 IBM Corporation 3e0017ebbSMatt Spinler * 4e0017ebbSMatt Spinler * Licensed under the Apache License, Version 2.0 (the "License"); 5e0017ebbSMatt Spinler * you may not use this file except in compliance with the License. 6e0017ebbSMatt Spinler * You may obtain a copy of the License at 7e0017ebbSMatt Spinler * 8e0017ebbSMatt Spinler * http://www.apache.org/licenses/LICENSE-2.0 9e0017ebbSMatt Spinler * 10e0017ebbSMatt Spinler * Unless required by applicable law or agreed to in writing, software 11e0017ebbSMatt Spinler * distributed under the License is distributed on an "AS IS" BASIS, 12e0017ebbSMatt Spinler * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e0017ebbSMatt Spinler * See the License for the specific language governing permissions and 14e0017ebbSMatt Spinler * limitations under the License. 15e0017ebbSMatt Spinler */ 16e0017ebbSMatt Spinler #include "config.h" 17e0017ebbSMatt Spinler #include "manager.hpp" 184a6ea6afSMatt Spinler #include "policy_find.hpp" 19e0017ebbSMatt Spinler 20e0017ebbSMatt Spinler namespace ibm 21e0017ebbSMatt Spinler { 22e0017ebbSMatt Spinler namespace logging 23e0017ebbSMatt Spinler { 24e0017ebbSMatt Spinler 25e0017ebbSMatt Spinler Manager::Manager(sdbusplus::bus::bus& bus) : 26e0017ebbSMatt Spinler bus(bus), 27259e7277SMatt Spinler addMatch(bus, 28e0017ebbSMatt Spinler sdbusplus::bus::match::rules::interfacesAdded() + 29e0017ebbSMatt Spinler sdbusplus::bus::match::rules::path_namespace(LOGGING_PATH), 30259e7277SMatt Spinler std::bind(std::mem_fn(&Manager::interfaceAdded), this, 31055da3bdSMatt Spinler std::placeholders::_1)), 32055da3bdSMatt Spinler removeMatch(bus, 33055da3bdSMatt Spinler sdbusplus::bus::match::rules::interfacesRemoved() + 34055da3bdSMatt Spinler sdbusplus::bus::match::rules::path_namespace(LOGGING_PATH), 35055da3bdSMatt Spinler std::bind(std::mem_fn(&Manager::interfaceRemoved), this, 36259e7277SMatt Spinler std::placeholders::_1)) 37743e5822SMatt Spinler #ifdef USE_POLICY_INTERFACE 38259e7277SMatt Spinler , 39259e7277SMatt Spinler policies(POLICY_JSON_PATH) 40743e5822SMatt Spinler #endif 41e0017ebbSMatt Spinler { 4254bfa7e7SMatt Spinler createAll(); 4354bfa7e7SMatt Spinler } 4454bfa7e7SMatt Spinler 4554bfa7e7SMatt Spinler void Manager::createAll() 4654bfa7e7SMatt Spinler { 47259e7277SMatt Spinler auto objects = getManagedObjects(bus, LOGGING_BUSNAME, LOGGING_PATH); 4854bfa7e7SMatt Spinler 4954bfa7e7SMatt Spinler for (const auto& object : objects) 5054bfa7e7SMatt Spinler { 5154bfa7e7SMatt Spinler const auto& interfaces = object.second; 5254bfa7e7SMatt Spinler 53*e6a51590SMatt Spinler auto propertyMap = interfaces.find(LOGGING_IFACE); 5454bfa7e7SMatt Spinler 5554bfa7e7SMatt Spinler if (propertyMap != interfaces.end()) 5654bfa7e7SMatt Spinler { 57*e6a51590SMatt Spinler createWithRestore(object.first, interfaces); 5854bfa7e7SMatt Spinler } 5954bfa7e7SMatt Spinler } 6054bfa7e7SMatt Spinler } 6154bfa7e7SMatt Spinler 62*e6a51590SMatt Spinler void Manager::createWithRestore(const std::string& objectPath, 63*e6a51590SMatt Spinler const DbusInterfaceMap& interfaces) 64*e6a51590SMatt Spinler { 65*e6a51590SMatt Spinler createObject(objectPath, interfaces); 66*e6a51590SMatt Spinler 67*e6a51590SMatt Spinler // TODO 68*e6a51590SMatt Spinler // restoreCalloutObjects(objectPath, interfaces); 69*e6a51590SMatt Spinler } 70*e6a51590SMatt Spinler 71259e7277SMatt Spinler void Manager::create(const std::string& objectPath, 72*e6a51590SMatt Spinler const DbusInterfaceMap& interfaces) 7354bfa7e7SMatt Spinler { 74*e6a51590SMatt Spinler createObject(objectPath, interfaces); 754a6ea6afSMatt Spinler 76*e6a51590SMatt Spinler // TODO 77*e6a51590SMatt Spinler // createCalloutObjects(objectPath, interfaces); 78*e6a51590SMatt Spinler } 79*e6a51590SMatt Spinler 80*e6a51590SMatt Spinler void Manager::createObject(const std::string& objectPath, 81*e6a51590SMatt Spinler const DbusInterfaceMap& interfaces) 82*e6a51590SMatt Spinler { 834a6ea6afSMatt Spinler #ifdef USE_POLICY_INTERFACE 84*e6a51590SMatt Spinler auto logInterface = interfaces.find(LOGGING_IFACE); 85*e6a51590SMatt Spinler createPolicyInterface(objectPath, logInterface->second); 864a6ea6afSMatt Spinler #endif 87e0017ebbSMatt Spinler } 88e0017ebbSMatt Spinler 89a1390353SMatt Spinler void Manager::erase(EntryID id) 90a1390353SMatt Spinler { 91677143bbSMatt Spinler childEntries.erase(id); 92a1390353SMatt Spinler entries.erase(id); 93a1390353SMatt Spinler } 94a1390353SMatt Spinler 95491fc6f1SMatt Spinler void Manager::addInterface(const std::string& objectPath, InterfaceType type, 96491fc6f1SMatt Spinler std::experimental::any& object) 97491fc6f1SMatt Spinler { 98491fc6f1SMatt Spinler auto id = getEntryID(objectPath); 99491fc6f1SMatt Spinler auto entry = entries.find(id); 100491fc6f1SMatt Spinler 101491fc6f1SMatt Spinler if (entry == entries.end()) 102491fc6f1SMatt Spinler { 103491fc6f1SMatt Spinler InterfaceMap interfaces; 104491fc6f1SMatt Spinler interfaces.emplace(type, object); 105491fc6f1SMatt Spinler entries.emplace(id, std::move(interfaces)); 106491fc6f1SMatt Spinler } 107491fc6f1SMatt Spinler else 108491fc6f1SMatt Spinler { 109491fc6f1SMatt Spinler entry->second.emplace(type, object); 110491fc6f1SMatt Spinler } 111491fc6f1SMatt Spinler } 112491fc6f1SMatt Spinler 113677143bbSMatt Spinler void Manager::addChildInterface(const std::string& objectPath, 114677143bbSMatt Spinler InterfaceType type, 115677143bbSMatt Spinler std::experimental::any& object) 116677143bbSMatt Spinler { 117677143bbSMatt Spinler auto id = getEntryID(objectPath); 118677143bbSMatt Spinler auto entry = childEntries.find(id); 119677143bbSMatt Spinler 120677143bbSMatt Spinler // childEntries is: 121677143bbSMatt Spinler // A map of error log entry IDs to: 122677143bbSMatt Spinler // a map of interface types to: 123677143bbSMatt Spinler // a vector of interface objects 124677143bbSMatt Spinler 125677143bbSMatt Spinler if (entry == childEntries.end()) 126677143bbSMatt Spinler { 127677143bbSMatt Spinler ObjectList objects{object}; 128677143bbSMatt Spinler InterfaceMapMulti interfaces; 129677143bbSMatt Spinler interfaces.emplace(type, std::move(objects)); 130677143bbSMatt Spinler childEntries.emplace(id, std::move(interfaces)); 131677143bbSMatt Spinler } 132677143bbSMatt Spinler else 133677143bbSMatt Spinler { 134677143bbSMatt Spinler auto i = entry->second.find(type); 135677143bbSMatt Spinler if (i == entry->second.end()) 136677143bbSMatt Spinler { 137677143bbSMatt Spinler ObjectList objects{objects}; 138677143bbSMatt Spinler entry->second.emplace(type, objects); 139677143bbSMatt Spinler } 140677143bbSMatt Spinler else 141677143bbSMatt Spinler { 142677143bbSMatt Spinler i->second.emplace_back(object); 143677143bbSMatt Spinler } 144677143bbSMatt Spinler } 145677143bbSMatt Spinler } 146677143bbSMatt Spinler 1474a6ea6afSMatt Spinler #ifdef USE_POLICY_INTERFACE 148259e7277SMatt Spinler void Manager::createPolicyInterface(const std::string& objectPath, 1494a6ea6afSMatt Spinler const DbusPropertyMap& properties) 1504a6ea6afSMatt Spinler { 1514a6ea6afSMatt Spinler auto values = policy::find(policies, properties); 1524a6ea6afSMatt Spinler 153259e7277SMatt Spinler auto object = std::make_shared<PolicyObject>(bus, objectPath.c_str(), true); 1544a6ea6afSMatt Spinler 1554a6ea6afSMatt Spinler object->eventID(std::get<policy::EIDField>(values)); 1564a6ea6afSMatt Spinler object->description(std::get<policy::MsgField>(values)); 1574a6ea6afSMatt Spinler 1589bea4eafSMatt Spinler object->emit_object_added(); 1599bea4eafSMatt Spinler 160491fc6f1SMatt Spinler std::experimental::any anyObject = object; 1614a6ea6afSMatt Spinler 162491fc6f1SMatt Spinler addInterface(objectPath, InterfaceType::POLICY, anyObject); 1634a6ea6afSMatt Spinler } 1644a6ea6afSMatt Spinler #endif 1654a6ea6afSMatt Spinler 166e0017ebbSMatt Spinler void Manager::interfaceAdded(sdbusplus::message::message& msg) 167e0017ebbSMatt Spinler { 168e0017ebbSMatt Spinler sdbusplus::message::object_path path; 169e0017ebbSMatt Spinler DbusInterfaceMap interfaces; 170e0017ebbSMatt Spinler 171e0017ebbSMatt Spinler msg.read(path, interfaces); 172e0017ebbSMatt Spinler 173e0017ebbSMatt Spinler // Find the Logging.Entry interface with all of its properties 174e0017ebbSMatt Spinler // to pass to create(). 175*e6a51590SMatt Spinler if (interfaces.find(LOGGING_IFACE) != interfaces.end()) 176e0017ebbSMatt Spinler { 177*e6a51590SMatt Spinler create(path, interfaces); 178e0017ebbSMatt Spinler } 179e0017ebbSMatt Spinler } 180055da3bdSMatt Spinler 181055da3bdSMatt Spinler void Manager::interfaceRemoved(sdbusplus::message::message& msg) 182055da3bdSMatt Spinler { 183055da3bdSMatt Spinler sdbusplus::message::object_path path; 184055da3bdSMatt Spinler DbusInterfaceList interfaces; 185055da3bdSMatt Spinler 186055da3bdSMatt Spinler msg.read(path, interfaces); 187055da3bdSMatt Spinler 188055da3bdSMatt Spinler // If the Logging.Entry interface was removed, then remove 189055da3bdSMatt Spinler // our object 190055da3bdSMatt Spinler 191055da3bdSMatt Spinler auto i = std::find(interfaces.begin(), interfaces.end(), LOGGING_IFACE); 192055da3bdSMatt Spinler 193055da3bdSMatt Spinler if (i != interfaces.end()) 194055da3bdSMatt Spinler { 195a1390353SMatt Spinler erase(getEntryID(path)); 196055da3bdSMatt Spinler } 197055da3bdSMatt Spinler } 198e0017ebbSMatt Spinler } 199e0017ebbSMatt Spinler } 200