Add a helper function copyRestFRUArea to updateFRUProperty
Refactoring updateFRUProperty function and created a new helper
function copyRestFRUArea. Moved this function to fru_utils.cpp
as it is common for all fru-device deamons and avoid code
duplication.
This patch is created based on suggestion on the below patch.
https://gerrit.openbmc.org/c/openbmc/entity-manager/+/51555
TESTED : Built Facebook YosemiteV2 images and loaded
on the target hardware. Verified all the fru's read and write.
Signed-off-by: Kumar Thangavel <thangavel.k@hcl.com>
Change-Id: I3a3ac6ff3190f0d91f5806e4824400cca0a590e4
Signed-off-by: Kumar Thangavel <thangavel.k@hcl.com>
diff --git a/include/fru_utils.hpp b/include/fru_utils.hpp
index d1784cd..0a988ef 100644
--- a/include/fru_utils.hpp
+++ b/include/fru_utils.hpp
@@ -68,6 +68,8 @@
size_t size; // Fru Area Size
size_t end; // Fru Area end offset
size_t updateFieldLoc; // Fru Area update Field Location
+ size_t restFieldsLoc; // Starting location of restFRUArea data
+ size_t restFieldsEnd; // Ending location of restFRUArea data
};
const std::vector<std::string> fruAreaNames = {"INTERNAL", "CHASSIS", "BOARD",
@@ -170,10 +172,25 @@
/// properties
/// \param fruData - vector to store fru data
/// \param propertyName - fru property Name
-/// \param fruAreaParams - struct to have fru Area paramteters like length,
-/// size. \return true if fru field is found, fruAreaParams are updated with
-/// fruArea and field info.
+/// \param fruAreaParams - struct to have fru Area parameters like length,
+/// size.
+/// \return true if fru field is found, fruAreaParams like updateFieldLoc,
+/// Start, Size, End are updated with fruArea and field info.
bool findFruAreaLocationAndField(std::vector<uint8_t>& fruData,
const std::string& propertyName,
- struct FruArea& fruAreaParams,
- size_t& fruDataIter);
+ struct FruArea& fruAreaParams);
+
+/// \brief Copy the fru Area fields and properties into restFRUAreaFieldsData.
+/// restFRUAreaField is the rest of the fields in FRU area after the field that
+/// is being updated.
+/// \param fruData - vector to store fru data
+/// \param propertyName - fru property Name
+/// \param fruAreaParams - struct to have fru Area parameters like length
+/// \param restFRUAreaFieldsData - vector to store fru Area Fields and
+/// properties.
+/// \return true on success false on failure. restFieldLoc and restFieldEnd
+/// are updated.
+bool copyRestFRUArea(std::vector<uint8_t>& fruData,
+ const std::string& propertyName,
+ struct FruArea& fruAreaParams,
+ std::vector<uint8_t>& restFRUAreaFieldsData);
diff --git a/src/fru_device.cpp b/src/fru_device.cpp
index 446d5c4..1e668ba 100644
--- a/src/fru_device.cpp
+++ b/src/fru_device.cpp
@@ -1107,42 +1107,20 @@
struct FruArea fruAreaParams
{};
- size_t fruDataIter = 0;
- if (!findFruAreaLocationAndField(fruData, propertyName, fruAreaParams,
- fruDataIter))
+ if (!findFruAreaLocationAndField(fruData, propertyName, fruAreaParams))
{
std::cerr << "findFruAreaLocationAndField failed \n";
return false;
}
- ssize_t fieldLength = 0;
-
- // Push post update fru field bytes to a vector
- fieldLength = getFieldLength(fruData[fruAreaParams.updateFieldLoc]);
- if (fieldLength < 0)
+ std::vector<uint8_t> restFRUAreaFieldsData;
+ if (!copyRestFRUArea(fruData, propertyName, fruAreaParams,
+ restFRUAreaFieldsData))
{
- std::cerr << "Property " << propertyName << " not present \n";
+ std::cerr << "copyRestFRUArea failed \n";
return false;
}
- fruDataIter += 1 + fieldLength;
- size_t restFRUFieldsLoc = fruDataIter;
- size_t endOfFieldsLoc = 0;
- while ((fieldLength = getFieldLength(fruData[fruDataIter])) >= 0)
- {
- if (fruDataIter >= (fruAreaParams.start + fruAreaParams.size))
- {
- fruDataIter = fruAreaParams.start + fruAreaParams.size;
- break;
- }
- fruDataIter += 1 + fieldLength;
- }
- endOfFieldsLoc = fruDataIter;
-
- std::vector<uint8_t> restFRUAreaFieldsData;
- std::copy_n(fruData.begin() + restFRUFieldsLoc,
- endOfFieldsLoc - restFRUFieldsLoc + 1,
- std::back_inserter(restFRUAreaFieldsData));
// Push post update fru areas if any
unsigned int nextFRUAreaLoc = 0;
@@ -1151,7 +1129,7 @@
{
unsigned int fruAreaLoc =
fruData[getHeaderAreaFieldOffset(nextFRUArea)] * fruBlockSize;
- if ((fruAreaLoc > endOfFieldsLoc) &&
+ if ((fruAreaLoc > fruAreaParams.restFieldsEnd) &&
((nextFRUAreaLoc == 0) || (fruAreaLoc < nextFRUAreaLoc)))
{
nextFRUAreaLoc = fruAreaLoc;
@@ -1200,10 +1178,13 @@
fruData.begin() + fruAreaParams.updateFieldLoc);
// Copy remaining data to main fru area - post updated fru field vector
- restFRUFieldsLoc = fruAreaParams.updateFieldLoc + updatePropertyReqLen;
- size_t fruAreaDataEnd = restFRUFieldsLoc + restFRUAreaFieldsData.size();
+ fruAreaParams.restFieldsLoc =
+ fruAreaParams.updateFieldLoc + updatePropertyReqLen;
+ size_t fruAreaDataEnd =
+ fruAreaParams.restFieldsLoc + restFRUAreaFieldsData.size();
+
std::copy(restFRUAreaFieldsData.begin(), restFRUAreaFieldsData.end(),
- fruData.begin() + restFRUFieldsLoc);
+ fruData.begin() + fruAreaParams.restFieldsLoc);
// Update final fru with new fru area length and checksum
unsigned int nextFRUAreaNewLoc = updateFRUAreaLenAndChecksum(
diff --git a/src/fru_utils.cpp b/src/fru_utils.cpp
index 4199439..bfcbdba 100644
--- a/src/fru_utils.cpp
+++ b/src/fru_utils.cpp
@@ -792,8 +792,7 @@
bool findFruAreaLocationAndField(std::vector<uint8_t>& fruData,
const std::string& propertyName,
- struct FruArea& fruAreaParams,
- size_t& fruDataIter)
+ struct FruArea& fruAreaParams)
{
const std::vector<std::string>* fruAreaFieldNames = nullptr;
@@ -840,7 +839,7 @@
fruAreaParams.start = fruAreaOffsetFieldValue * fruBlockSize;
fruAreaParams.size = fruData[fruAreaParams.start + 1] * fruBlockSize;
fruAreaParams.end = fruAreaParams.start + fruAreaParams.size;
- fruDataIter = fruAreaParams.start + offset;
+ size_t fruDataIter = fruAreaParams.start + offset;
size_t skipToFRUUpdateField = 0;
ssize_t fieldLength = 0;
@@ -892,3 +891,53 @@
return true;
}
+
+// Copy the FRU Area fields and properties into restFRUAreaFieldsData vector.
+// Return true for success and false for failure.
+
+bool copyRestFRUArea(std::vector<uint8_t>& fruData,
+ const std::string& propertyName,
+ struct FruArea& fruAreaParams,
+ std::vector<uint8_t>& restFRUAreaFieldsData)
+{
+ size_t fieldLoc = fruAreaParams.updateFieldLoc;
+ size_t start = fruAreaParams.start;
+ size_t fruAreaSize = fruAreaParams.size;
+
+ // Push post update fru field bytes to a vector
+ ssize_t fieldLength = getFieldLength(fruData[fieldLoc]);
+ if (fieldLength < 0)
+ {
+ std::cerr << "Property " << propertyName << " not present \n";
+ return false;
+ }
+
+ size_t fruDataIter = 0;
+ fruDataIter = fieldLoc;
+ fruDataIter += 1 + fieldLength;
+ size_t restFRUFieldsLoc = fruDataIter;
+ size_t endOfFieldsLoc = 0;
+
+ if (fruDataIter < fruData.size())
+ {
+ while ((fieldLength = getFieldLength(fruData[fruDataIter])) >= 0)
+ {
+ if (fruDataIter >= (start + fruAreaSize))
+ {
+ fruDataIter = start + fruAreaSize;
+ break;
+ }
+ fruDataIter += 1 + fieldLength;
+ }
+ endOfFieldsLoc = fruDataIter;
+ }
+
+ std::copy_n(fruData.begin() + restFRUFieldsLoc,
+ endOfFieldsLoc - restFRUFieldsLoc + 1,
+ std::back_inserter(restFRUAreaFieldsData));
+
+ fruAreaParams.restFieldsLoc = restFRUFieldsLoc;
+ fruAreaParams.restFieldsEnd = endOfFieldsLoc;
+
+ return true;
+}