149aefb31SBrad Bishop /** 249aefb31SBrad Bishop * Copyright © 2016 IBM Corporation 349aefb31SBrad Bishop * 449aefb31SBrad Bishop * Licensed under the Apache License, Version 2.0 (the "License"); 549aefb31SBrad Bishop * you may not use this file except in compliance with the License. 649aefb31SBrad Bishop * You may obtain a copy of the License at 749aefb31SBrad Bishop * 849aefb31SBrad Bishop * http://www.apache.org/licenses/LICENSE-2.0 949aefb31SBrad Bishop * 1049aefb31SBrad Bishop * Unless required by applicable law or agreed to in writing, software 1149aefb31SBrad Bishop * distributed under the License is distributed on an "AS IS" BASIS, 1249aefb31SBrad Bishop * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1349aefb31SBrad Bishop * See the License for the specific language governing permissions and 1449aefb31SBrad Bishop * limitations under the License. 1549aefb31SBrad Bishop */ 1649aefb31SBrad Bishop #include <iostream> 1749aefb31SBrad Bishop #include <exception> 1824424983SBrad Bishop #include <chrono> 199bbfcb18SBrad Bishop #include <log.hpp> 2049aefb31SBrad Bishop #include "manager.hpp" 2149aefb31SBrad Bishop 2224424983SBrad Bishop using namespace std::literals::chrono_literals; 2324424983SBrad Bishop 2449aefb31SBrad Bishop namespace phosphor 2549aefb31SBrad Bishop { 2649aefb31SBrad Bishop namespace inventory 2749aefb31SBrad Bishop { 2849aefb31SBrad Bishop namespace manager 2949aefb31SBrad Bishop { 3049aefb31SBrad Bishop /** @brief Fowrarding signal callback. 3149aefb31SBrad Bishop * 3249aefb31SBrad Bishop * Extracts per-signal specific context and forwards the call to the manager 3349aefb31SBrad Bishop * instance. 3449aefb31SBrad Bishop */ 3549aefb31SBrad Bishop auto _signal(sd_bus_message* m, void* data, sd_bus_error* e) noexcept 3649aefb31SBrad Bishop { 377b33777bSBrad Bishop try 387b33777bSBrad Bishop { 3949aefb31SBrad Bishop auto msg = sdbusplus::message::message(m); 4049aefb31SBrad Bishop auto& args = *static_cast<Manager::SigArg*>(data); 4149aefb31SBrad Bishop sd_bus_message_ref(m); 4249aefb31SBrad Bishop auto& mgr = *std::get<0>(args); 4348547a85SBrad Bishop mgr.handleEvent( 4468c80839SBrad Bishop msg, 4512f8a3c8SBrad Bishop static_cast<const DbusSignal&>( 4668c80839SBrad Bishop *std::get<1>(args)), 4768c80839SBrad Bishop *std::get<2>(args)); 4849aefb31SBrad Bishop } 497b33777bSBrad Bishop catch (const std::exception& e) 507b33777bSBrad Bishop { 5149aefb31SBrad Bishop std::cerr << e.what() << std::endl; 5249aefb31SBrad Bishop } 5349aefb31SBrad Bishop 5449aefb31SBrad Bishop return 0; 5549aefb31SBrad Bishop } 5649aefb31SBrad Bishop 5749aefb31SBrad Bishop Manager::Manager( 5849aefb31SBrad Bishop sdbusplus::bus::bus&& bus, 5949aefb31SBrad Bishop const char* busname, 6049aefb31SBrad Bishop const char* root, 6149aefb31SBrad Bishop const char* iface) : 6212f8a3c8SBrad Bishop ServerObject<ManagerIface>(bus, root), 6349aefb31SBrad Bishop _shutdown(false), 6449aefb31SBrad Bishop _root(root), 6549aefb31SBrad Bishop _bus(std::move(bus)), 6649aefb31SBrad Bishop _manager(sdbusplus::server::manager::manager(_bus, root)) 6749aefb31SBrad Bishop { 6868c80839SBrad Bishop for (auto& group : _events) 6968c80839SBrad Bishop { 7012f8a3c8SBrad Bishop for (auto pEvent : std::get<std::vector<EventBasePtr>>( 7148547a85SBrad Bishop group)) 7268c80839SBrad Bishop { 734f20a3e3SBrad Bishop if (pEvent->type != 7412f8a3c8SBrad Bishop Event::Type::DBUS_SIGNAL) 757b33777bSBrad Bishop { 764f20a3e3SBrad Bishop continue; 777b33777bSBrad Bishop } 784f20a3e3SBrad Bishop 7968c80839SBrad Bishop // Create a callback context for this event group. 8012f8a3c8SBrad Bishop auto dbusEvent = static_cast<DbusSignal*>( 8168c80839SBrad Bishop pEvent.get()); 8268c80839SBrad Bishop 8368c80839SBrad Bishop // Go ahead and store an iterator pointing at 8468c80839SBrad Bishop // the event data to avoid lookups later since 8568c80839SBrad Bishop // additional signal callbacks aren't added 8668c80839SBrad Bishop // after the manager is constructed. 8749aefb31SBrad Bishop _sigargs.emplace_back( 8849aefb31SBrad Bishop std::make_unique<SigArg>( 8949aefb31SBrad Bishop this, 9068c80839SBrad Bishop dbusEvent, 911ab880a1SBrad Bishop &group)); 9268c80839SBrad Bishop 9349aefb31SBrad Bishop // Register our callback and the context for 9468c80839SBrad Bishop // each signal event. 9549aefb31SBrad Bishop _matches.emplace_back( 9649aefb31SBrad Bishop _bus, 9748547a85SBrad Bishop dbusEvent->signature, 9812f8a3c8SBrad Bishop _signal, 991ab880a1SBrad Bishop _sigargs.back().get()); 10049aefb31SBrad Bishop } 10168c80839SBrad Bishop } 10249aefb31SBrad Bishop 10349aefb31SBrad Bishop _bus.request_name(busname); 10449aefb31SBrad Bishop } 10549aefb31SBrad Bishop 10649aefb31SBrad Bishop void Manager::shutdown() noexcept 10749aefb31SBrad Bishop { 10849aefb31SBrad Bishop _shutdown = true; 10949aefb31SBrad Bishop } 11049aefb31SBrad Bishop 11149aefb31SBrad Bishop void Manager::run() noexcept 11249aefb31SBrad Bishop { 1133e4a19a3SBrad Bishop sdbusplus::message::message unusedMsg{nullptr}; 1143e4a19a3SBrad Bishop 1153e4a19a3SBrad Bishop // Run startup events. 1163e4a19a3SBrad Bishop for (auto& group : _events) 1173e4a19a3SBrad Bishop { 11812f8a3c8SBrad Bishop for (auto pEvent : std::get<std::vector<EventBasePtr>>( 1193e4a19a3SBrad Bishop group)) 1203e4a19a3SBrad Bishop { 1213e4a19a3SBrad Bishop if (pEvent->type == 12212f8a3c8SBrad Bishop Event::Type::STARTUP) 1233e4a19a3SBrad Bishop { 1243e4a19a3SBrad Bishop handleEvent(unusedMsg, *pEvent, group); 1253e4a19a3SBrad Bishop } 1263e4a19a3SBrad Bishop } 1273e4a19a3SBrad Bishop } 1283e4a19a3SBrad Bishop 1297b33777bSBrad Bishop while (!_shutdown) 1307b33777bSBrad Bishop { 1317b33777bSBrad Bishop try 1327b33777bSBrad Bishop { 13349aefb31SBrad Bishop _bus.process_discard(); 13424424983SBrad Bishop _bus.wait((5000000us).count()); 13549aefb31SBrad Bishop } 1367b33777bSBrad Bishop catch (const std::exception& e) 1377b33777bSBrad Bishop { 13849aefb31SBrad Bishop std::cerr << e.what() << std::endl; 13949aefb31SBrad Bishop } 14049aefb31SBrad Bishop } 14149aefb31SBrad Bishop } 14249aefb31SBrad Bishop 14303f4cd95SBrad Bishop void Manager::notify(std::map<sdbusplus::message::object_path, Object> objs) 14449aefb31SBrad Bishop { 145*cda036f7SBrad Bishop updateObjects(objs); 14649aefb31SBrad Bishop } 14749aefb31SBrad Bishop 14848547a85SBrad Bishop void Manager::handleEvent( 14968c80839SBrad Bishop sdbusplus::message::message& msg, 15012f8a3c8SBrad Bishop const Event& event, 15168c80839SBrad Bishop const EventInfo& info) 15249aefb31SBrad Bishop { 15368c80839SBrad Bishop auto& actions = std::get<1>(info); 1543d57f507SBrad Bishop 15548547a85SBrad Bishop for (auto& f : event) 1567b33777bSBrad Bishop { 15707934a64SBrad Bishop if (!f(_bus, msg, *this)) 158064c94a6SBrad Bishop { 159064c94a6SBrad Bishop return; 160064c94a6SBrad Bishop } 161064c94a6SBrad Bishop } 1629007432aSBrad Bishop for (auto& action : actions) 1637b33777bSBrad Bishop { 16407934a64SBrad Bishop action(_bus, *this); 1653d57f507SBrad Bishop } 16649aefb31SBrad Bishop } 16749aefb31SBrad Bishop 1687b7e712cSBrad Bishop void Manager::destroyObjects( 1697b7e712cSBrad Bishop const std::vector<const char*>& paths) 1707b7e712cSBrad Bishop { 171a5cc34c2SBrad Bishop std::string p; 172a5cc34c2SBrad Bishop 1737b7e712cSBrad Bishop for (const auto& path : paths) 174656a7d00SBrad Bishop { 175a5cc34c2SBrad Bishop p.assign(_root); 176a5cc34c2SBrad Bishop p.append(path); 177a5cc34c2SBrad Bishop _bus.emit_object_removed(p.c_str()); 178a5cc34c2SBrad Bishop _refs.erase(p); 179656a7d00SBrad Bishop } 1807b7e712cSBrad Bishop } 181656a7d00SBrad Bishop 182eb68a687SBrad Bishop void Manager::createObjects( 183eb68a687SBrad Bishop const std::map<sdbusplus::message::object_path, Object>& objs) 184eb68a687SBrad Bishop { 185*cda036f7SBrad Bishop updateObjects(objs); 186eb68a687SBrad Bishop } 187eb68a687SBrad Bishop 188150147aeSBrad Bishop any_ns::any& Manager::getInterfaceHolder( 189b83a21eaSBrad Bishop const char* path, const char* interface) 190b83a21eaSBrad Bishop { 191150147aeSBrad Bishop return const_cast<any_ns::any&>( 192150147aeSBrad Bishop const_cast<const Manager*>( 193150147aeSBrad Bishop this)->getInterfaceHolder(path, interface)); 194b83a21eaSBrad Bishop } 195b83a21eaSBrad Bishop 196150147aeSBrad Bishop const any_ns::any& Manager::getInterfaceHolder( 197b83a21eaSBrad Bishop const char* path, const char* interface) const 198b83a21eaSBrad Bishop { 199b83a21eaSBrad Bishop std::string p{path}; 200b83a21eaSBrad Bishop auto oit = _refs.find(_root + p); 201b83a21eaSBrad Bishop if (oit == _refs.end()) 202b83a21eaSBrad Bishop throw std::runtime_error( 203b83a21eaSBrad Bishop _root + p + " was not found"); 204b83a21eaSBrad Bishop 205b83a21eaSBrad Bishop auto& obj = oit->second; 206b83a21eaSBrad Bishop auto iit = obj.find(interface); 207b83a21eaSBrad Bishop if (iit == obj.end()) 208b83a21eaSBrad Bishop throw std::runtime_error( 209b83a21eaSBrad Bishop "interface was not found"); 210b83a21eaSBrad Bishop 211150147aeSBrad Bishop return iit->second; 212b83a21eaSBrad Bishop } 213b83a21eaSBrad Bishop 21449aefb31SBrad Bishop } // namespace manager 21549aefb31SBrad Bishop } // namespace inventory 21649aefb31SBrad Bishop } // namespace phosphor 21749aefb31SBrad Bishop 21849aefb31SBrad Bishop // vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4 219