fru-device: move Adding and updating a property into a helper
Adds updating and adding properties to a helper function
that's divorced from dbus logic. This allows other code
to modify a fru buffer.
Tested:
Called updateproperty on nvl32-obmc. Result was correct
Change-Id: I432f89003cf5608900c018f72edef877534bfe40
Signed-off-by: Marc Olberding <molberding@nvidia.com>
diff --git a/src/fru_device/fru_device.cpp b/src/fru_device/fru_device.cpp
index 1b2de93..324afcd 100644
--- a/src/fru_device/fru_device.cpp
+++ b/src/fru_device/fru_device.cpp
@@ -1212,16 +1212,6 @@
"updateFruProperty called: FieldName = {NAME}, FieldValue = {VALUE}",
"NAME", propertyName, "VALUE", propertyValue);
- // Validate field length: must be 2–63 characters
- const size_t len = propertyValue.length();
- if (len == 1 || len > 63)
- {
- lg2::error(
- "FRU field data must be 0 or between 2 and 63 characters. Invalid Length: {LEN}",
- "LEN", len);
- return false;
- }
-
std::vector<uint8_t> fruData;
if (!getFruData(fruData, bus, address))
{
@@ -1230,69 +1220,12 @@
return false;
}
- if (fruData.empty())
+ bool success = updateAddProperty(propertyValue, propertyName, fruData);
+ if (!success)
{
- lg2::error("Empty FRU data\n");
- return false;
- }
-
- // Extract area name (prefix before underscore)
- std::string areaName = propertyName.substr(0, propertyName.find('_'));
- auto areaIterator =
- std::find(fruAreaNames.begin(), fruAreaNames.end(), areaName);
- if (areaIterator == fruAreaNames.end())
- {
- lg2::error("Failed to get FRU area for property: {AREA}", "AREA",
- areaName);
- return false;
- }
-
- fruAreas fruAreaToUpdate = static_cast<fruAreas>(
- std::distance(fruAreaNames.begin(), areaIterator));
-
- std::vector<std::vector<uint8_t>> areasData;
- if (!disassembleFruData(fruData, areasData))
- {
- lg2::error("Failed to disassemble Fru Data");
- return false;
- }
-
- std::vector<uint8_t>& areaData =
- areasData[static_cast<size_t>(fruAreaToUpdate)];
- if (areaData.empty())
- {
- // If ENABLE_FRU_AREA_RESIZE is not defined then return with failure
-#ifndef ENABLE_FRU_AREA_RESIZE
lg2::error(
- "FRU area {AREA} not present and ENABLE_FRU_AREA_RESIZE is not set. "
- "Returning failure.",
- "AREA", areaName);
- return false;
-#endif
- if (!createDummyArea(fruAreaToUpdate, areaData))
- {
- lg2::error("Failed to create dummy area for {AREA}", "AREA",
- areaName);
- return false;
- }
- }
-
- if (!setField(fruAreaToUpdate, areaData, propertyName, propertyValue))
- {
- lg2::error("Failed to set field value for property: {PROPERTY}",
- "PROPERTY", propertyName);
- return false;
- }
-
- if (!assembleFruData(fruData, areasData))
- {
- lg2::error("Failed to reassemble FRU data");
- return false;
- }
-
- if (fruData.empty())
- {
- lg2::error("FRU data is empty after assembly");
+ "Failed to update the property on bus {BUS}, address {ADDRESS}",
+ "BUS", bus, "ADDRESS", address);
return false;
}
diff --git a/src/fru_device/fru_utils.cpp b/src/fru_device/fru_utils.cpp
index 385ea72..c9669de 100644
--- a/src/fru_device/fru_utils.cpp
+++ b/src/fru_device/fru_utils.cpp
@@ -1667,3 +1667,86 @@
// Match against editable fields
return std::ranges::contains(editableFields, subField);
}
+
+bool updateAddProperty(const std::string& propertyValue,
+ const std::string& propertyName,
+ std::vector<uint8_t>& fruData)
+{
+ // Validate field length: must be 2–63 characters
+ const size_t len = propertyValue.length();
+ if (len == 1 || len > 63)
+ {
+ lg2::error(
+ "FRU field data must be 0 or between 2 and 63 characters. Invalid Length: {LEN}",
+ "LEN", len);
+ return false;
+ }
+
+ if (fruData.empty())
+ {
+ lg2::error("Empty FRU data\n");
+ return false;
+ }
+
+ // Extract area name (prefix before underscore)
+ std::string areaName = propertyName.substr(0, propertyName.find('_'));
+ auto areaIterator =
+ std::find(fruAreaNames.begin(), fruAreaNames.end(), areaName);
+ if (areaIterator == fruAreaNames.end())
+ {
+ lg2::error("Failed to get FRU area for property: {AREA}", "AREA",
+ areaName);
+ return false;
+ }
+
+ fruAreas fruAreaToUpdate = static_cast<fruAreas>(
+ std::distance(fruAreaNames.begin(), areaIterator));
+
+ std::vector<std::vector<uint8_t>> areasData;
+ if (!disassembleFruData(fruData, areasData))
+ {
+ lg2::error("Failed to disassemble Fru Data");
+ return false;
+ }
+
+ std::vector<uint8_t>& areaData =
+ areasData[static_cast<size_t>(fruAreaToUpdate)];
+ if (areaData.empty())
+ {
+ // If ENABLE_FRU_AREA_RESIZE is not defined then return with failure
+#ifndef ENABLE_FRU_AREA_RESIZE
+ lg2::error(
+ "FRU area {AREA} not present and ENABLE_FRU_AREA_RESIZE is not set. "
+ "Returning failure.",
+ "AREA", areaName);
+ return false;
+#endif
+ if (!createDummyArea(fruAreaToUpdate, areaData))
+ {
+ lg2::error("Failed to create dummy area for {AREA}", "AREA",
+ areaName);
+ return false;
+ }
+ }
+
+ if (!setField(fruAreaToUpdate, areaData, propertyName, propertyValue))
+ {
+ lg2::error("Failed to set field value for property: {PROPERTY}",
+ "PROPERTY", propertyName);
+ return false;
+ }
+
+ if (!assembleFruData(fruData, areasData))
+ {
+ lg2::error("Failed to reassemble FRU data");
+ return false;
+ }
+
+ if (fruData.empty())
+ {
+ lg2::error("FRU data is empty after assembly");
+ return false;
+ }
+
+ return true;
+}
diff --git a/src/fru_device/fru_utils.hpp b/src/fru_device/fru_utils.hpp
index 2b32362..0491b30 100644
--- a/src/fru_device/fru_utils.hpp
+++ b/src/fru_device/fru_utils.hpp
@@ -226,3 +226,7 @@
bool setField(const fruAreas& fruAreaToUpdate, std::vector<uint8_t>& areaData,
const std::string& propertyName, const std::string& value);
+
+bool updateAddProperty(const std::string& propertyValue,
+ const std::string& propertyName,
+ std::vector<uint8_t>& data);