Add manager skeleton
Add stubbed Notify implementation and register for generated
signal callbacks.
Add a unit test; which, at this point does little more than
verify we don't coredump on startup.
Change-Id: I0cda71935947c0d082612a5c52e2b7eba98516ab
Signed-off-by: Brad Bishop <bradleyb@fuzziesquirrel.com>
diff --git a/manager.cpp b/manager.cpp
new file mode 100644
index 0000000..36d47a6
--- /dev/null
+++ b/manager.cpp
@@ -0,0 +1,164 @@
+/**
+ * Copyright © 2016 IBM Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <iostream>
+#include <exception>
+#include "manager.hpp"
+
+namespace phosphor
+{
+namespace inventory
+{
+namespace manager
+{
+namespace details
+{
+
+/** @brief Fowrarding signal callback.
+ *
+ * Extracts per-signal specific context and forwards the call to the manager
+ * instance.
+ */
+auto _signal(sd_bus_message *m, void *data, sd_bus_error *e) noexcept
+{
+ try {
+ auto msg = sdbusplus::message::message(m);
+ auto &args = *static_cast<Manager::SigArg*>(data);
+ sd_bus_message_ref(m);
+ auto &mgr = *std::get<0>(args);
+ mgr.signal(msg, *std::get<1>(args));
+ }
+ catch (const std::exception &e) {
+ std::cerr << e.what() << std::endl;
+ }
+
+ return 0;
+}
+
+} // namespace details
+
+Manager::Manager(
+ sdbusplus::bus::bus &&bus,
+ const char *busname,
+ const char *root,
+ const char *iface) :
+ sdbusplus::server::xyz::openbmc_project::Inventory::Manager(bus, root),
+ _shutdown(false),
+ _root(root),
+ _bus(std::move(bus)),
+ _manager(sdbusplus::server::manager::manager(_bus, root))
+{
+ for (auto &x: _events) {
+ // Create a callback context for each event.
+ _sigargs.emplace_back(
+ std::make_unique<SigArg>(
+ std::make_tuple(
+ this,
+ &x.second)));
+ // Register our callback and the context for
+ // each event.
+ _matches.emplace_back(
+ sdbusplus::server::match::match(
+ _bus,
+ std::get<0>(x.second),
+ details::_signal,
+ _sigargs.back().get()));
+ }
+
+ _bus.request_name(busname);
+}
+
+void Manager::shutdown() noexcept
+{
+ _shutdown = true;
+}
+
+void Manager::run() noexcept
+{
+ while(!_shutdown) {
+ try {
+ _bus.process_discard();
+ _bus.wait(5000000);
+ }
+ catch (const std::exception &e) {
+ std::cerr << e.what() << std::endl;
+ }
+ }
+}
+
+void Manager::notify(std::string path, Object object)
+{
+ try {
+ using MakerType = HolderPtr(*)(
+ sdbusplus::bus::bus &, const char *);
+ using Makers = std::map<std::string, MakerType>;
+
+ if(object.cbegin() == object.cend())
+ throw std::runtime_error(
+ "No interfaces in " + path);
+
+ static const Makers makers{
+ // TODO - Add mappings here.
+ };
+
+ path.insert(0, _root);
+
+ auto obj = _refs.find(path);
+ if(obj != _refs.end())
+ throw std::runtime_error(
+ obj->first + " already exists");
+
+ // Create an interface holder for each interface
+ // provided by the client and group them into
+ // a container.
+ InterfaceComposite ref;
+
+ for (auto &x: object) {
+ auto maker = makers.find(x.first.c_str());
+
+ if(maker == makers.end())
+ throw std::runtime_error(
+ "Unimplemented interface: " + x.first);
+
+ ref.emplace(
+ std::make_pair(
+ x.first,
+ (maker->second)(_bus, path.c_str())));
+ }
+
+ // Hang on to a reference to the object (interfaces)
+ // so it stays on the bus, and so we can make calls
+ // to it if needed.
+ _refs.emplace(
+ std::make_pair(
+ path, std::move(ref)));
+ }
+ catch (const std::exception &e) {
+ std::cerr << e.what() << std::endl;
+ }
+}
+
+void Manager::signal(sdbusplus::message::message &msg, auto &args)
+{
+ // TODO - unstub
+}
+
+#include "generated.hpp"
+
+} // namespace manager
+} // namespace inventory
+} // namespace phosphor
+
+// vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4