oem:ibm :Implement SetFruRecordTable

The commit implements the setFruRecordTable command
and also updates the DBus property for the IBM cable cards
for which the host sends a setFruRecordTable command.

Tested: using pldmtool

Signed-off-by: Pavithra Barithaya <pavithra.b@ibm.com>
Change-Id: I70e4f85f627577d8ca1bc90447b10e9e2e8e7ccd
diff --git a/libpldmresponder/fru.cpp b/libpldmresponder/fru.cpp
index 8a04199..58c3316 100644
--- a/libpldmresponder/fru.cpp
+++ b/libpldmresponder/fru.cpp
@@ -429,6 +429,24 @@
     return PLDM_SUCCESS;
 }
 
+int FruImpl::setFRUTable(const std::vector<uint8_t>& fruData)
+{
+    auto record =
+        reinterpret_cast<const pldm_fru_record_data_format*>(fruData.data());
+    if (record)
+    {
+        if (oemFruHandler && record->record_type == PLDM_FRU_RECORD_TYPE_OEM)
+        {
+            auto rc = oemFruHandler->processOEMFRUTable(fruData);
+            if (!rc)
+            {
+                return PLDM_SUCCESS;
+            }
+        }
+    }
+    return PLDM_ERROR_UNSUPPORTED_PLDM_CMD;
+}
+
 namespace fru
 {
 Response Handler::getFRURecordTableMetadata(const pldm_msg* request,
@@ -539,6 +557,44 @@
     return response;
 }
 
+Response Handler::setFRURecordTable(const pldm_msg* request,
+                                    size_t payloadLength)
+{
+    uint32_t transferHandle{};
+    uint8_t transferOpFlag{};
+    struct variable_field fruData;
+
+    auto rc = decode_set_fru_record_table_req(
+        request, payloadLength, &transferHandle, &transferOpFlag, &fruData);
+
+    if (rc != PLDM_SUCCESS)
+    {
+        return ccOnlyResponse(request, rc);
+    }
+
+    Table table(fruData.ptr, fruData.ptr + fruData.length);
+    rc = impl.setFRUTable(table);
+    if (rc != PLDM_SUCCESS)
+    {
+        return ccOnlyResponse(request, rc);
+    }
+
+    Response response(sizeof(pldm_msg_hdr) +
+                      PLDM_SET_FRU_RECORD_TABLE_RESP_BYTES);
+    struct pldm_msg* responsePtr = reinterpret_cast<pldm_msg*>(response.data());
+
+    rc = encode_set_fru_record_table_resp(
+        request->hdr.instance_id, PLDM_SUCCESS, 0 /* nextDataTransferHandle */,
+        response.size() - sizeof(pldm_msg_hdr), responsePtr);
+
+    if (rc != PLDM_SUCCESS)
+    {
+        return ccOnlyResponse(request, rc);
+    }
+
+    return response;
+}
+
 } // namespace fru
 
 } // namespace responder