blob: 0c6831e5f40bda9863be6c9801b07760ae69e9d5 [file] [log] [blame]
Brad Bishop49aefb32016-10-19 11:54:14 -04001/**
2 * Copyright © 2016 IBM 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#include <iostream>
17#include <exception>
Brad Bishop24424982017-01-13 16:37:14 -050018#include <chrono>
Brad Bishop9bbfcb12017-02-04 10:51:06 -050019#include <log.hpp>
Brad Bishop49aefb32016-10-19 11:54:14 -040020#include "manager.hpp"
21
Brad Bishop24424982017-01-13 16:37:14 -050022using namespace std::literals::chrono_literals;
23
Brad Bishop49aefb32016-10-19 11:54:14 -040024namespace phosphor
25{
26namespace inventory
27{
28namespace manager
29{
Brad Bishop49aefb32016-10-19 11:54:14 -040030/** @brief Fowrarding signal callback.
31 *
32 * Extracts per-signal specific context and forwards the call to the manager
33 * instance.
34 */
Brad Bishop7b337772017-01-12 16:11:24 -050035auto _signal(sd_bus_message* m, void* data, sd_bus_error* e) noexcept
Brad Bishop49aefb32016-10-19 11:54:14 -040036{
Brad Bishop7b337772017-01-12 16:11:24 -050037 try
38 {
Brad Bishop49aefb32016-10-19 11:54:14 -040039 auto msg = sdbusplus::message::message(m);
Brad Bishop7b337772017-01-12 16:11:24 -050040 auto& args = *static_cast<Manager::SigArg*>(data);
Brad Bishop49aefb32016-10-19 11:54:14 -040041 sd_bus_message_ref(m);
Brad Bishop7b337772017-01-12 16:11:24 -050042 auto& mgr = *std::get<0>(args);
Brad Bishop48547a82017-01-19 15:12:50 -050043 mgr.handleEvent(
Brad Bishop7b337772017-01-12 16:11:24 -050044 msg,
Brad Bishop12f8a3c2017-02-09 00:02:00 -050045 static_cast<const DbusSignal&>(
Brad Bishop7b337772017-01-12 16:11:24 -050046 *std::get<1>(args)),
47 *std::get<2>(args));
Brad Bishop49aefb32016-10-19 11:54:14 -040048 }
Brad Bishop7b337772017-01-12 16:11:24 -050049 catch (const std::exception& e)
50 {
Brad Bishop49aefb32016-10-19 11:54:14 -040051 std::cerr << e.what() << std::endl;
52 }
53
54 return 0;
55}
56
Brad Bishop49aefb32016-10-19 11:54:14 -040057Manager::Manager(
Brad Bishop7b337772017-01-12 16:11:24 -050058 sdbusplus::bus::bus&& bus,
59 const char* busname,
60 const char* root,
61 const char* iface) :
Brad Bishop12f8a3c2017-02-09 00:02:00 -050062 ServerObject<ManagerIface>(bus, root),
Brad Bishop49aefb32016-10-19 11:54:14 -040063 _shutdown(false),
64 _root(root),
65 _bus(std::move(bus)),
66 _manager(sdbusplus::server::manager::manager(_bus, root))
67{
Brad Bishop7b337772017-01-12 16:11:24 -050068 for (auto& group : _events)
Brad Bishop68c80832016-11-29 16:41:32 -050069 {
Brad Bishop12f8a3c2017-02-09 00:02:00 -050070 for (auto pEvent : std::get<std::vector<EventBasePtr>>(
Brad Bishop48547a82017-01-19 15:12:50 -050071 group))
Brad Bishop68c80832016-11-29 16:41:32 -050072 {
73 if (pEvent->type !=
Brad Bishop12f8a3c2017-02-09 00:02:00 -050074 Event::Type::DBUS_SIGNAL)
Brad Bishop7b337772017-01-12 16:11:24 -050075 {
Brad Bishop68c80832016-11-29 16:41:32 -050076 continue;
Brad Bishop7b337772017-01-12 16:11:24 -050077 }
Brad Bishop4f20a3e2016-11-29 15:21:46 -050078
Brad Bishop68c80832016-11-29 16:41:32 -050079 // Create a callback context for this event group.
Brad Bishop12f8a3c2017-02-09 00:02:00 -050080 auto dbusEvent = static_cast<DbusSignal*>(
Brad Bishop7b337772017-01-12 16:11:24 -050081 pEvent.get());
Brad Bishop68c80832016-11-29 16:41:32 -050082
83 // Go ahead and store an iterator pointing at
84 // the event data to avoid lookups later since
85 // additional signal callbacks aren't added
86 // after the manager is constructed.
87 _sigargs.emplace_back(
Brad Bishop7b337772017-01-12 16:11:24 -050088 std::make_unique<SigArg>(
89 this,
90 dbusEvent,
91 &group));
Brad Bishop68c80832016-11-29 16:41:32 -050092
93 // Register our callback and the context for
94 // each signal event.
95 _matches.emplace_back(
Brad Bishop7b337772017-01-12 16:11:24 -050096 _bus,
Brad Bishop48547a82017-01-19 15:12:50 -050097 dbusEvent->signature,
Brad Bishop12f8a3c2017-02-09 00:02:00 -050098 _signal,
Brad Bishop7b337772017-01-12 16:11:24 -050099 _sigargs.back().get());
Brad Bishop68c80832016-11-29 16:41:32 -0500100 }
Brad Bishop49aefb32016-10-19 11:54:14 -0400101 }
102
103 _bus.request_name(busname);
104}
105
106void Manager::shutdown() noexcept
107{
108 _shutdown = true;
109}
110
111void Manager::run() noexcept
112{
Brad Bishop3e4a19a2017-01-21 22:17:09 -0500113 sdbusplus::message::message unusedMsg{nullptr};
114
115 // Run startup events.
116 for (auto& group : _events)
117 {
Brad Bishop12f8a3c2017-02-09 00:02:00 -0500118 for (auto pEvent : std::get<std::vector<EventBasePtr>>(
Brad Bishop3e4a19a2017-01-21 22:17:09 -0500119 group))
120 {
121 if (pEvent->type ==
Brad Bishop12f8a3c2017-02-09 00:02:00 -0500122 Event::Type::STARTUP)
Brad Bishop3e4a19a2017-01-21 22:17:09 -0500123 {
124 handleEvent(unusedMsg, *pEvent, group);
125 }
126 }
127 }
128
Brad Bishop7b337772017-01-12 16:11:24 -0500129 while (!_shutdown)
130 {
131 try
132 {
Brad Bishop49aefb32016-10-19 11:54:14 -0400133 _bus.process_discard();
Brad Bishop24424982017-01-13 16:37:14 -0500134 _bus.wait((5000000us).count());
Brad Bishop49aefb32016-10-19 11:54:14 -0400135 }
Brad Bishop7b337772017-01-12 16:11:24 -0500136 catch (const std::exception& e)
137 {
Brad Bishop49aefb32016-10-19 11:54:14 -0400138 std::cerr << e.what() << std::endl;
139 }
140 }
141}
142
Brad Bishop03f4cd92017-02-03 15:17:21 -0500143void Manager::notify(std::map<sdbusplus::message::object_path, Object> objs)
Brad Bishop49aefb32016-10-19 11:54:14 -0400144{
Brad Bishopcda036f2017-02-15 10:06:48 -0500145 updateObjects(objs);
Brad Bishop49aefb32016-10-19 11:54:14 -0400146}
147
Brad Bishop48547a82017-01-19 15:12:50 -0500148void Manager::handleEvent(
Brad Bishop7b337772017-01-12 16:11:24 -0500149 sdbusplus::message::message& msg,
Brad Bishop12f8a3c2017-02-09 00:02:00 -0500150 const Event& event,
Brad Bishop7b337772017-01-12 16:11:24 -0500151 const EventInfo& info)
Brad Bishop49aefb32016-10-19 11:54:14 -0400152{
Brad Bishop7b337772017-01-12 16:11:24 -0500153 auto& actions = std::get<1>(info);
Brad Bishop3d57f502016-10-19 12:18:41 -0400154
Brad Bishop48547a82017-01-19 15:12:50 -0500155 for (auto& f : event)
Brad Bishop7b337772017-01-12 16:11:24 -0500156 {
Brad Bishop07934a62017-02-08 23:34:59 -0500157 if (!f(_bus, msg, *this))
Brad Bishop7b337772017-01-12 16:11:24 -0500158 {
Brad Bishop064c94a2017-01-21 21:33:30 -0500159 return;
Brad Bishop7b337772017-01-12 16:11:24 -0500160 }
Brad Bishop3d57f502016-10-19 12:18:41 -0400161 }
Brad Bishop064c94a2017-01-21 21:33:30 -0500162 for (auto& action : actions)
163 {
Brad Bishop07934a62017-02-08 23:34:59 -0500164 action(_bus, *this);
Brad Bishop064c94a2017-01-21 21:33:30 -0500165 }
Brad Bishop49aefb32016-10-19 11:54:14 -0400166}
167
Brad Bishop7b7e7122017-01-21 21:21:46 -0500168void Manager::destroyObjects(
169 const std::vector<const char*>& paths)
Brad Bishop656a7d02016-10-19 22:20:02 -0400170{
Brad Bishopa5cc34c2017-02-03 20:57:36 -0500171 std::string p;
172
Brad Bishop7b7e7122017-01-21 21:21:46 -0500173 for (const auto& path : paths)
174 {
Brad Bishopa5cc34c2017-02-03 20:57:36 -0500175 p.assign(_root);
176 p.append(path);
177 _bus.emit_object_removed(p.c_str());
178 _refs.erase(p);
Brad Bishop7b7e7122017-01-21 21:21:46 -0500179 }
Brad Bishop656a7d02016-10-19 22:20:02 -0400180}
181
Brad Bishopeb68a682017-01-22 00:58:54 -0500182void Manager::createObjects(
183 const std::map<sdbusplus::message::object_path, Object>& objs)
184{
Brad Bishopcda036f2017-02-15 10:06:48 -0500185 updateObjects(objs);
Brad Bishopeb68a682017-01-22 00:58:54 -0500186}
187
Brad Bishop150147a2017-02-08 23:57:46 -0500188any_ns::any& Manager::getInterfaceHolder(
Brad Bishop7b337772017-01-12 16:11:24 -0500189 const char* path, const char* interface)
Brad Bishopb83a21e2016-11-30 13:43:37 -0500190{
Brad Bishop150147a2017-02-08 23:57:46 -0500191 return const_cast<any_ns::any&>(
192 const_cast<const Manager*>(
193 this)->getInterfaceHolder(path, interface));
Brad Bishopb83a21e2016-11-30 13:43:37 -0500194}
195
Brad Bishop150147a2017-02-08 23:57:46 -0500196const any_ns::any& Manager::getInterfaceHolder(
Brad Bishop7b337772017-01-12 16:11:24 -0500197 const char* path, const char* interface) const
Brad Bishopb83a21e2016-11-30 13:43:37 -0500198{
199 std::string p{path};
200 auto oit = _refs.find(_root + p);
Brad Bishop7b337772017-01-12 16:11:24 -0500201 if (oit == _refs.end())
Brad Bishopb83a21e2016-11-30 13:43:37 -0500202 throw std::runtime_error(
Brad Bishop7b337772017-01-12 16:11:24 -0500203 _root + p + " was not found");
Brad Bishopb83a21e2016-11-30 13:43:37 -0500204
Brad Bishop7b337772017-01-12 16:11:24 -0500205 auto& obj = oit->second;
Brad Bishopb83a21e2016-11-30 13:43:37 -0500206 auto iit = obj.find(interface);
Brad Bishop7b337772017-01-12 16:11:24 -0500207 if (iit == obj.end())
Brad Bishopb83a21e2016-11-30 13:43:37 -0500208 throw std::runtime_error(
Brad Bishop7b337772017-01-12 16:11:24 -0500209 "interface was not found");
Brad Bishopb83a21e2016-11-30 13:43:37 -0500210
Brad Bishop150147a2017-02-08 23:57:46 -0500211 return iit->second;
Brad Bishopb83a21e2016-11-30 13:43:37 -0500212}
213
Brad Bishop49aefb32016-10-19 11:54:14 -0400214} // namespace manager
215} // namespace inventory
216} // namespace phosphor
217
218// vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4