cleanup: move devicetree_vpd_parser into separate directory

Improving repository structure for increasing maintainability.

Change-Id: Iad9d6e350f3bae48fa11a412d3cff5379390744f
Signed-off-by: Christopher Meis <christopher.meis@9elements.com>
diff --git a/src/devicetree_vpd_parser/devicetree_vpd_parser.cpp b/src/devicetree_vpd_parser/devicetree_vpd_parser.cpp
new file mode 100644
index 0000000..87bd2d7
--- /dev/null
+++ b/src/devicetree_vpd_parser/devicetree_vpd_parser.cpp
@@ -0,0 +1,44 @@
+#include "machine_context.hpp"
+
+#include <memory>
+
+int main()
+{
+    static constexpr auto reqDBusPath = "/xyz/openbmc_project/MachineContext";
+    static constexpr auto reqDBusName = "xyz.openbmc_project.MachineContext";
+
+    /*Note: OpenBMC convention typically has service name = bus name,
+    where the bus name is representative of the underlying hardware.
+
+    In the case of MachineContext, the BMC is not gathering data from
+    specific hardware, but is instead parsing device-tree nodes for
+    context about the hardware OpenBMC is running on.
+
+    Because the VPD data being parsed is coming from device-tree,
+    the daemon and matching service name reflect that.
+
+    Because the parsed data represents 'machine context' data,
+    the bus name and associated path the daemon writes to
+    reflects that instead.
+    */
+
+    sdbusplus::async::context ctx;
+    sdbusplus::server::manager_t manager{ctx, reqDBusPath};
+
+    std::unique_ptr<MachineContext> mc = nullptr;
+    if (MachineContext::keyNodeExists())
+    {
+        mc = std::make_unique<MachineContext>(ctx, reqDBusPath);
+        mc->populateFromDeviceTree();
+    }
+
+    // NOLINTNEXTLINE(readability-static-accessed-through-instance)
+    ctx.spawn([](sdbusplus::async::context& ctx) -> sdbusplus::async::task<> {
+        ctx.request_name(reqDBusName);
+        co_return;
+    }(ctx));
+
+    ctx.run();
+
+    return 0;
+};
diff --git a/src/devicetree_vpd_parser/machine_context.cpp b/src/devicetree_vpd_parser/machine_context.cpp
new file mode 100644
index 0000000..6f2c956
--- /dev/null
+++ b/src/devicetree_vpd_parser/machine_context.cpp
@@ -0,0 +1,45 @@
+/*
+// Copyright (c) 2024 Hewlett Packard Enterprise
+//
+// 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 "machine_context.hpp"
+
+#include <filesystem>
+#include <fstream>
+
+void MachineContext::populateFromDeviceTree()
+{
+    std::string nodeVal;
+    std::ifstream vpdStream(nodeBasePath + std::string("model"));
+    if (vpdStream && std::getline(vpdStream, nodeVal))
+    {
+        MachineContext::Asset::model(nodeVal);
+        vpdStream.close();
+    }
+
+    vpdStream.open(nodeBasePath + std::string("serial-number"));
+    if (vpdStream && std::getline(vpdStream, nodeVal))
+    {
+        MachineContext::Asset::serial_number(nodeVal);
+        vpdStream.close();
+    }
+};
+
+bool MachineContext::keyNodeExists()
+{
+    std::filesystem::path nodePath{nodeBasePath + std::string("model")};
+
+    return std::filesystem::exists(nodePath);
+};
diff --git a/src/devicetree_vpd_parser/machine_context.hpp b/src/devicetree_vpd_parser/machine_context.hpp
new file mode 100644
index 0000000..fca2a33
--- /dev/null
+++ b/src/devicetree_vpd_parser/machine_context.hpp
@@ -0,0 +1,37 @@
+/*
+// Copyright (c) 2024 Hewlett Packard Enterprise
+//
+// 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.
+*/
+
+#pragma once
+
+#include <sdbusplus/async.hpp>
+#include <xyz/openbmc_project/Inventory/Decorator/Asset/aserver.hpp>
+
+class MachineContext :
+    public sdbusplus::aserver::xyz::openbmc_project::inventory::decorator::
+        Asset<MachineContext>
+{
+  public:
+    explicit MachineContext(sdbusplus::async::context& ctx, auto path) :
+        sdbusplus::aserver::xyz::openbmc_project::inventory::decorator::Asset<
+            MachineContext>(ctx, path) {};
+
+    void populateFromDeviceTree();
+
+    static bool keyNodeExists();
+
+  private:
+    static constexpr auto nodeBasePath = "/proc/device-tree/";
+};
diff --git a/src/devicetree_vpd_parser/meson.build b/src/devicetree_vpd_parser/meson.build
new file mode 100644
index 0000000..93e6f98
--- /dev/null
+++ b/src/devicetree_vpd_parser/meson.build
@@ -0,0 +1,11 @@
+cpp_args_fd = cpp_args
+executable(
+    'devicetree-vpd-parser',
+    'machine_context.cpp',
+    'devicetree_vpd_parser.cpp',
+    cpp_args: cpp_args_fd,
+    dependencies: [sdbusplus, phosphor_dbus_interfaces_dep],
+    install: true,
+    install_dir: installdir,
+)
+