diff --git a/vpd_tool_impl.cpp b/vpd_tool_impl.cpp
new file mode 100644
index 0000000..ccc2765
--- /dev/null
+++ b/vpd_tool_impl.cpp
@@ -0,0 +1,234 @@
+#include "vpd_tool_impl.hpp"
+
+#include <iostream>
+#include <sdbusplus/bus.hpp>
+#include <sstream>
+#include <variant>
+#include <vector>
+
+using namespace std;
+using sdbusplus::exception::SdBusError;
+using namespace openpower::vpd;
+
+void VpdTool::debugger(json output)
+{
+    cout << output.dump(4) << '\n';
+}
+
+auto VpdTool::makeDBusCall(const string& objectName, const string& interface,
+                           const string& kw)
+{
+    auto bus = sdbusplus::bus::new_default();
+    auto properties =
+        bus.new_method_call(INVENTORY_MANAGER_SERVICE, objectName.c_str(),
+                            "org.freedesktop.DBus.Properties", "Get");
+    properties.append(interface);
+    properties.append(kw);
+    auto result = bus.call(properties);
+
+    if (result.is_method_error())
+    {
+        throw runtime_error("Get api failed");
+    }
+    return result;
+}
+
+void VpdTool::addFruTypeAndLocation(json exIntf, const string& object,
+                                    json& kwVal)
+{
+    for (const auto& intf : exIntf.items())
+    {
+        if ((intf.key().find("Item") != string::npos) &&
+            (intf.value().is_null()))
+        {
+            kwVal.emplace("type", intf.key());
+            break;
+        }
+    }
+
+    // Add location code.
+    constexpr auto LOCATION_CODE_IF = "com.ibm.ipzvpd.Location";
+    constexpr auto LOCATION_CODE_PROP = "LocationCode";
+
+    try
+    {
+        variant<string> response;
+        makeDBusCall(object, LOCATION_CODE_IF, LOCATION_CODE_PROP)
+            .read(response);
+
+        if (auto prop = get_if<string>(&response))
+        {
+            kwVal.emplace(LOCATION_CODE_PROP, *prop);
+        }
+    }
+    catch (const SdBusError& e)
+    {
+        kwVal.emplace(LOCATION_CODE_PROP, "");
+    }
+}
+
+json VpdTool::getVINIProperties(string invPath, json exIntf)
+{
+    variant<Binary> response;
+    json output = json::object({});
+    json kwVal = json::object({});
+
+    vector<string> keyword{"CC", "SN", "PN", "FN", "DR"};
+    string interface = "com.ibm.ipzvpd.VINI";
+    string objectName = INVENTORY_PATH + invPath;
+
+    for (string kw : keyword)
+    {
+        try
+        {
+            makeDBusCall(objectName, interface, kw).read(response);
+
+            if (auto vec = get_if<Binary>(&response))
+            {
+                kwVal.emplace(kw, string(vec->begin(), vec->end()));
+            }
+        }
+        catch (const SdBusError& e)
+        {
+            output.emplace(invPath, json::object({}));
+        }
+    }
+
+    addFruTypeAndLocation(exIntf, objectName, kwVal);
+    output.emplace(invPath, kwVal);
+    return output;
+}
+
+void VpdTool::getExtraInterfaceProperties(string invPath, string extraInterface,
+                                          json prop, json exIntf, json& output)
+{
+    variant<string> response;
+
+    string objectName = INVENTORY_PATH + invPath;
+
+    for (const auto& itProp : prop.items())
+    {
+        string kw = itProp.key();
+        try
+        {
+            makeDBusCall(objectName, extraInterface, kw).read(response);
+
+            if (auto str = get_if<string>(&response))
+            {
+                output.emplace(kw, *str);
+            }
+        }
+        catch (const SdBusError& e)
+        {
+            output.emplace(invPath, json::object({}));
+        }
+    }
+    addFruTypeAndLocation(exIntf, objectName, output);
+}
+
+json VpdTool::interfaceDecider(json& itemEEPROM)
+{
+    if (itemEEPROM.find("inventoryPath") == itemEEPROM.end())
+    {
+        throw runtime_error("Inventory Path not found");
+    }
+
+    if (itemEEPROM.find("extraInterfaces") == itemEEPROM.end())
+    {
+        throw runtime_error("Extra Interfaces not found");
+    }
+
+    bool exIntfCheck = false;
+    json output = json::object({});
+
+    if (itemEEPROM.value("inherit", true))
+    {
+        json j = getVINIProperties(itemEEPROM.at("inventoryPath"),
+                                   itemEEPROM["extraInterfaces"]);
+        output.insert(j.begin(), j.end());
+    }
+    else
+    {
+        json js;
+        for (const auto& ex : itemEEPROM["extraInterfaces"].items())
+        {
+            if (!(ex.value().is_null()))
+            {
+                exIntfCheck = true;
+                getExtraInterfaceProperties(itemEEPROM.at("inventoryPath"),
+                                            ex.key(), ex.value(),
+                                            itemEEPROM["extraInterfaces"], js);
+            }
+        }
+        output.emplace(itemEEPROM.at("inventoryPath"), js);
+    }
+    return output;
+}
+
+json VpdTool::parseInvJson(const json& jsObject, char flag, string fruPath)
+{
+    json output = json::object({});
+    bool validObject = false;
+
+    if (jsObject.find("frus") == jsObject.end())
+    {
+        throw runtime_error("Frus missing in Inventory json");
+    }
+    else
+    {
+        for (const auto& itemFRUS : jsObject["frus"].items())
+        {
+            for (auto itemEEPROM : itemFRUS.value())
+            {
+                try
+                {
+                    if (flag == 'O')
+                    {
+                        if (itemEEPROM.find("inventoryPath") ==
+                            itemEEPROM.end())
+                        {
+                            throw runtime_error("Inventory Path not found");
+                        }
+
+                        else if (itemEEPROM.at("inventoryPath") == fruPath)
+                        {
+                            validObject = true;
+                            json j = interfaceDecider(itemEEPROM);
+                            output.insert(j.begin(), j.end());
+                            return output;
+                        }
+                    }
+                    else
+                    {
+                        json j = interfaceDecider(itemEEPROM);
+                        output.insert(j.begin(), j.end());
+                    }
+                }
+                catch (exception& e)
+                {
+                    cerr << e.what();
+                }
+            }
+        }
+        if ((flag == 'O') && (!validObject))
+        {
+            throw runtime_error(
+                "Invalid object path. Refer --dumpInventory/-i option.");
+        }
+    }
+    return output;
+}
+
+void VpdTool::dumpInventory(const nlohmann::basic_json<>& jsObject)
+{
+    char flag = 'I';
+    json output = parseInvJson(jsObject, flag, "");
+    debugger(output);
+}
+
+void VpdTool::dumpObject(const nlohmann::basic_json<>& jsObject)
+{
+    char flag = 'O';
+    json output = parseInvJson(jsObject, flag, fruPath);
+    debugger(output);
+}
