summaryrefslogtreecommitdiffstats
path: root/writefrudata.cpp
diff options
context:
space:
mode:
authorRatan Gupta <ratagupt@in.ibm.com>2016-12-22 19:05:57 +0530
committerRatan Gupta <ratagupt@in.ibm.com>2017-02-01 21:44:24 +0530
commitcb0d4e5e8caefd9f62c676cb1084f3d22bc330d5 (patch)
treef9e0a57f35f18895bfb24ee148a1e25707553feb /writefrudata.cpp
parent82ab3e19d58d56edcc2c6a1193a7ff38e310ef76 (diff)
downloadipmi-fru-parser-cb0d4e5e8caefd9f62c676cb1084f3d22bc330d5.tar.gz
ipmi-fru-parser-cb0d4e5e8caefd9f62c676cb1084f3d22bc330d5.zip
Re-factor to use MRW and Inventory interfaces
The write FRU command now figures out properties to be written for a FRU via a generated header file, which in turn is generated via scrips deriving their inputs from MRW and Inventory d-bus interfaces. Change-Id: I9939aeec24566cf518f4e63dc6ae344b236a541f Signed-off-by: Ratan Gupta <ratagupt@in.ibm.com>
Diffstat (limited to 'writefrudata.cpp')
-rw-r--r--writefrudata.cpp202
1 files changed, 130 insertions, 72 deletions
diff --git a/writefrudata.cpp b/writefrudata.cpp
index 3619966..3e09bc8 100644
--- a/writefrudata.cpp
+++ b/writefrudata.cpp
@@ -14,11 +14,22 @@
#include <mapper.h>
#include "frup.h"
#include "fru-area.hpp"
+#include "fru-gen.hpp"
// OpenBMC System Manager dbus framework
const char *sys_object_name = "/org/openbmc/managers/System";
const char *sys_intf_name = "org.openbmc.managers.System";
+extern const FruMap frus;
+
+// Association between interface and the dbus property
+using InterfaceList = std::map<std::string,
+ std::map<std::string, std::string>>;
+
+// Association between property and its value
+using PropertiesList = std::map<std::string, std::string>;
+
+
//----------------------------------------------------------------
// Constructor
//----------------------------------------------------------------
@@ -343,98 +354,145 @@ int verify_fru_data(const uint8_t *data, const size_t len)
}
//------------------------------------------------------------------------
-// Takes FRU data, invokes Parser for each fru record area and updates
-// Inventory
+// Gets the value of the key from the fru dictionary of the given section.
+// FRU dictionary is parsed fru data for all the sections.
//------------------------------------------------------------------------
-int ipmi_update_inventory(fru_area_vec_t & area_vec)
+
+std::string getFRUValue(const std::string& section,
+ const std::string& key,
+ IPMIFruInfo& fruData)
{
- // Generic error reporter
- int rc = 0;
- // Dictionary object to hold Name:Value pair
- sd_bus_message *fru_dict = NULL;
+ auto minIndexValue = 0;
+ auto maxIndexValue = 0;
+ std::string fruValue = "";
+ if (section == "Board")
+ {
+ minIndexValue = OPENBMC_VPD_KEY_BOARD_MFG_DATE;
+ maxIndexValue = OPENBMC_VPD_KEY_BOARD_MAX;
+ }
+ else if (section == "Product")
+ {
+ minIndexValue = OPENBMC_VPD_KEY_PRODUCT_MFR;
+ maxIndexValue = OPENBMC_VPD_KEY_PRODUCT_MAX;
- // SD Bus error report mechanism.
- sd_bus_error bus_error = SD_BUS_ERROR_NULL;
+ }
+ else if (section == "Chassis")
+ {
+ minIndexValue = OPENBMC_VPD_KEY_CHASSIS_TYPE;
+ maxIndexValue = OPENBMC_VPD_KEY_CHASSIS_MAX;
+ }
- // Response from sd bus calls
- sd_bus_message *response = NULL;
+ auto first = fruData.cbegin() + minIndexValue;
+ auto last = first + (maxIndexValue - minIndexValue) + 1;
- // For each FRU area, extract the needed data , get it parsed and update
- // the Inventory.
- for(auto& iter : area_vec)
+ auto itr = std::find_if(first, last,
+ [&key](auto& e){ return key == e.first; });
+
+ if (itr != last)
{
- // Start fresh on each.
- sd_bus_error_free(&bus_error);
- sd_bus_message_unref(response);
- sd_bus_message_unref(fru_dict);
-
- // Constructor to allow further initializations and customization.
- rc = sd_bus_message_new_method_call((iter)->get_bus_type(),
- &fru_dict,
- (iter)->get_bus_name(),
- (iter)->get_obj_path(),
- (iter)->get_intf_name(),
- "update");
- if(rc < 0)
- {
- fprintf(stderr,"ERROR: creating a update method call for bus_name:[%s]\n",
- (iter)->get_bus_name());
- break;
- }
+ fruValue = itr->second;
+ }
+ return fruValue;
- // A Dictionary ({}) having (string, variant)
- rc = sd_bus_message_open_container(fru_dict, 'a', "{sv}");
- if(rc < 0)
+}
+
+// TODO: Remove once the call to inventory manager is added
+auto print = [](const InterfaceList& object, const std::string& path)
+{
+ std::cout << "\n";
+ std::cout << path << "\n";
+ std::cout << "\n";
+ for(const auto& o : object)
+ {
+ std::cout << o.first << "\n";
+ for(const auto& i : o.second)
{
- fprintf(stderr,"ERROR:[%d] creating a dict container:\n",errno);
- break;
+ std::cout << i.first << " : " << i.second << "\n";
}
+ std::cout << "\n";
+ }
+};
+//------------------------------------------------------------------------
+// Takes FRU data, invokes Parser for each fru record area and updates
+// Inventory
+//------------------------------------------------------------------------
+int ipmi_update_inventory(fru_area_vec_t& area_vec)
+{
+ // Generic error reporter
+ int rc = 0;
+ uint8_t fruid = 0;
+ IPMIFruInfo fruData;
+
+ // For each FRU area, extract the needed data , get it parsed and update
+ // the Inventory.
+ for (const auto& fruArea : area_vec)
+ {
+ fruid = fruArea->get_fruid();
// Fill the container with information
- rc = parse_fru_area((iter)->get_type(), (void *)(iter)->get_data(), (iter)->get_len(), fru_dict);
- if(rc < 0)
+ rc = parse_fru_area((fruArea)->get_type(), (void*)(fruArea)->get_data(),
+ (fruArea)->get_len(), fruData);
+ if (rc < 0)
{
- fprintf(stderr,"ERROR parsing FRU records\n");
- break;
+ std::cerr << "ERROR parsing FRU records\n";
+ return rc;
}
+ } // END walking the vector of areas and updating
- sd_bus_message_close_container(fru_dict);
+ // For each Fru we have the list of instances which needs to be updated.
+ // Each instance object implements certain interfaces.
+ // Each Interface is having Dbus properties.
+ // Each Dbus Property would be having metaData(eg section,VpdPropertyName).
- // Now, Make the actual call to update the FRU inventory database with the
- // dictionary given by FRU Parser. There is no response message expected for
- // this.
- rc = sd_bus_call((iter)->get_bus_type(), // On the System Bus
- fru_dict, // With the Name:value dictionary array
- 0, //
- &bus_error, // Object to return error.
- &response); // Response message if any.
+ // Here we are just printing the object,interface and the properties.
+ // which needs to be called with the new inventory manager implementation.
+ // TODO:- Call the new Inventory Manager.
+ auto iter = frus.find(fruid);
+ if (iter == frus.end())
+ {
+ std::cerr << "ERROR Unable to get the fru info for FRU=" << fruid << "\n";
+ return -1;
+ }
+ auto& instanceList = iter->second;
- if(rc < 0)
- {
- fprintf(stderr, "ERROR:[%s] updating FRU inventory for ID:[0x%X]\n",
- bus_error.message, (iter)->get_fruid());
- break;
- }
- else if((iter)->is_bmc_fru())
- {
- // For FRUs that are accessible by HostBoot, host boot does all of
- // these.
- printf("SUCCESS: Updated:[%s_%d] successfully. Setting Valid bit\n",
- (iter)->get_name(), (iter)->get_fruid());
+ if (instanceList.size() <= 0)
+ {
+ std::cout << "Object List empty for this FRU=" << fruid << "\n";
+ }
+ for (auto& instance : instanceList)
+ {
+ InterfaceList interfaces;
- (iter)->set_valid(true);
- }
- else
+ for (auto& interfaceList : instance.second)
{
- printf("SUCCESS: Updated:[%s_%d] successfully\n",
- (iter)->get_name(), (iter)->get_fruid());
- }
- } // END walking the vector of areas and updating
+ PropertiesList prop;//store all the properties
+ for (auto& properties : interfaceList.second)
+ {
+ std::string section, property, value;
+ for (auto& info : properties.second)
+ {
+ if (info.first == "IPMIFruSection")
+ {
+ section = std::move(info.second);
+ }
+ if (info.first == "IPMIFruProperty")
+ {
+ property = std::move(info.second);
+ }
+ }
- sd_bus_error_free(&bus_error);
- sd_bus_message_unref(response);
- sd_bus_message_unref(fru_dict);
+ if (!section.empty() && !property.empty())
+ {
+ value = getFRUValue(section, property, fruData);
+ }
+ prop.emplace(std::move(properties.first), std::move(value));
+ }
+ interfaces.emplace(std::move(interfaceList.first), std::move(prop));
+ }
+ //TODO:- remove it later with the inventory manager call.
+ print(interfaces, instance.first);
+ }
return rc;
}
OpenPOWER on IntegriCloud