libpldm: decode APIs for pldmPDRRepositoryChgEvent
Change-Id: I5ee1280ed4033e8f8033808b0e150c75c2f01d01
Signed-off-by: Zahed Hossain <zahzahed@in.ibm.com>
diff --git a/libpldm/platform.c b/libpldm/platform.c
index 4c74b9b..97692a9 100644
--- a/libpldm/platform.c
+++ b/libpldm/platform.c
@@ -946,3 +946,61 @@
}
return PLDM_SUCCESS;
}
+
+int decode_pldm_pdr_repository_chg_event_data(const uint8_t *event_data,
+ size_t event_data_size,
+ uint8_t *event_data_format,
+ uint8_t *number_of_change_records,
+ size_t *change_record_data_offset)
+{
+ if (event_data == NULL || event_data_format == NULL ||
+ number_of_change_records == NULL ||
+ change_record_data_offset == NULL) {
+ return PLDM_ERROR_INVALID_DATA;
+ }
+ if (event_data_size < PLDM_PDR_REPOSITORY_CHG_EVENT_MIN_LENGTH) {
+ return PLDM_ERROR_INVALID_LENGTH;
+ }
+
+ struct pldm_pdr_repository_chg_event_data
+ *pdr_repository_chg_event_data =
+ (struct pldm_pdr_repository_chg_event_data *)event_data;
+
+ *event_data_format = pdr_repository_chg_event_data->event_data_format;
+ *number_of_change_records =
+ pdr_repository_chg_event_data->number_of_change_records;
+ *change_record_data_offset =
+ sizeof(*event_data_format) + sizeof(*number_of_change_records);
+
+ return PLDM_SUCCESS;
+}
+
+int decode_pldm_pdr_repository_change_record_data(
+ const uint8_t *change_record_data, size_t change_record_data_size,
+ uint8_t *event_data_operation, uint8_t *number_of_change_entries,
+ size_t *change_entry_data_offset)
+{
+ if (change_record_data == NULL || event_data_operation == NULL ||
+ number_of_change_entries == NULL ||
+ change_entry_data_offset == NULL) {
+ return PLDM_ERROR_INVALID_DATA;
+ }
+ if (change_record_data_size <
+ PLDM_PDR_REPOSITORY_CHANGE_RECORD_MIN_LENGTH) {
+ return PLDM_ERROR_INVALID_LENGTH;
+ }
+
+ struct pldm_pdr_repository_change_record_data
+ *pdr_repository_change_record_data =
+ (struct pldm_pdr_repository_change_record_data *)
+ change_record_data;
+
+ *event_data_operation =
+ pdr_repository_change_record_data->event_data_operation;
+ *number_of_change_entries =
+ pdr_repository_change_record_data->number_of_change_entries;
+ *change_entry_data_offset =
+ sizeof(*event_data_operation) + sizeof(*number_of_change_entries);
+
+ return PLDM_SUCCESS;
+}
diff --git a/libpldm/platform.h b/libpldm/platform.h
index dd99633..1805f7d 100644
--- a/libpldm/platform.h
+++ b/libpldm/platform.h
@@ -42,6 +42,10 @@
#define PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_16BIT_DATA_LENGTH 5
#define PLDM_SENSOR_EVENT_NUMERIC_SENSOR_STATE_32BIT_DATA_LENGTH 7
+/* Minimum length of data for pldmPDRRepositoryChgEvent */
+#define PLDM_PDR_REPOSITORY_CHG_EVENT_MIN_LENGTH 2
+#define PLDM_PDR_REPOSITORY_CHANGE_RECORD_MIN_LENGTH 2
+
enum pldm_effecter_data_size {
PLDM_EFFECTER_DATA_SIZE_UINT8,
PLDM_EFFECTER_DATA_SIZE_SINT8,
@@ -174,6 +178,16 @@
FORMAT_IS_PDR_HANDLES
};
+/** @brief PLDM pldmPDRRepositoryChgEvent class changeRecord format
+ * eventDataOperation
+ */
+enum pldm_pdr_repository_chg_event_change_record_event_data_operation {
+ PLDM_REFRESH_ALL_RECORDS,
+ PLDM_RECORDS_DELETED,
+ PLDM_RECORDS_ADDED,
+ PLDM_RECORDS_MODIFIED
+};
+
/** @brief PLDM NumericSensorStatePresentReading data type
*/
enum pldm_sensor_readings_data_type {
@@ -976,6 +990,45 @@
uint8_t *effecter_data_size, uint8_t *effecter_oper_state,
uint8_t *pending_value, uint8_t *present_value);
+/** @brief Decode pldmPDRRepositoryChgEvent response data
+ *
+ * @param[in] event_data - eventData for pldmPDRRepositoryChgEvent
+ * @param[in] event_data_size - Length of event_data
+ * @param[out] event_data_format - This field indicates if the changedRecords
+ * are of PDR Types or PDR Record Handles
+ * @param[out] number_of_change_records - The number of changeRecords following
+ * this field
+ * @param[out] change_record_data_offset - Identifies where changeRecord data
+ * is located within event_data
+ * @return pldm_completion_codes
+ * @note Caller is responsible for memory alloc and dealloc of param
+ * 'event_data'
+ */
+int decode_pldm_pdr_repository_chg_event_data(
+ const uint8_t *event_data, size_t event_data_size,
+ uint8_t *event_data_format, uint8_t *number_of_change_records,
+ size_t *change_record_data_offset);
+
+/** @brief Decode PldmPDRRepositoryChangeRecord response data
+ *
+ * @param[in] change_record_data - changeRecordData for
+ * pldmPDRRepositoryChgEvent
+ * @param[in] change_record_data_size - Length of change_record_data
+ * @param[out] event_data_operation - This field indicates the changeEntries
+ * operation types
+ * @param[out] number_of_change_entries - The number of changeEntries following
+ * this field
+ * @param[out] change_entry_data_offset - Identifies where changeEntries data
+ * is located within change_record_data
+ * @return pldm_completion_codes
+ * @note Caller is responsible for memory alloc and dealloc of param
+ * 'change_record_data'
+ */
+int decode_pldm_pdr_repository_change_record_data(
+ const uint8_t *change_record_data, size_t change_record_data_size,
+ uint8_t *event_data_operation, uint8_t *number_of_change_entries,
+ size_t *change_entry_data_offset);
+
#ifdef __cplusplus
}
#endif
diff --git a/libpldm/tests/libpldm_platform_test.cpp b/libpldm/tests/libpldm_platform_test.cpp
index 9e790c2..1958ca0 100644
--- a/libpldm/tests/libpldm_platform_test.cpp
+++ b/libpldm/tests/libpldm_platform_test.cpp
@@ -1361,3 +1361,120 @@
EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
}
+
+TEST(PldmPDRRepositoryChgEventEvent, testGoodDecodeRequest)
+{
+ const uint8_t eventDataFormat = FORMAT_IS_PDR_HANDLES;
+ const uint8_t numberOfChangeRecords = 2;
+ uint8_t eventDataOperation1 = PLDM_RECORDS_DELETED;
+ const uint8_t numberOfChangeEntries1 = 2;
+ std::array<uint32_t, numberOfChangeEntries1> changeRecordArr1{
+ {0x00000000, 0x12345678}};
+ uint8_t eventDataOperation2 = PLDM_RECORDS_ADDED;
+ const uint8_t numberOfChangeEntries2 = 5;
+ std::array<uint32_t, numberOfChangeEntries2> changeRecordArr2{
+ {0x01234567, 0x11223344, 0x45678901, 0x21222324, 0x98765432}};
+ std::array<uint8_t, PLDM_PDR_REPOSITORY_CHG_EVENT_MIN_LENGTH +
+ PLDM_PDR_REPOSITORY_CHANGE_RECORD_MIN_LENGTH *
+ numberOfChangeRecords +
+ (numberOfChangeEntries1 + numberOfChangeEntries2) *
+ sizeof(uint32_t)>
+ eventDataArr{};
+
+ struct pldm_pdr_repository_chg_event_data* eventData =
+ reinterpret_cast<struct pldm_pdr_repository_chg_event_data*>(
+ eventDataArr.data());
+ eventData->event_data_format = eventDataFormat;
+ eventData->number_of_change_records = numberOfChangeRecords;
+ struct pldm_pdr_repository_change_record_data* changeRecord1 =
+ reinterpret_cast<struct pldm_pdr_repository_change_record_data*>(
+ eventData->change_records);
+ changeRecord1->event_data_operation = eventDataOperation1;
+ changeRecord1->number_of_change_entries = numberOfChangeEntries1;
+ memcpy(changeRecord1->change_entry, &changeRecordArr1[0],
+ changeRecordArr1.size() * sizeof(uint32_t));
+ struct pldm_pdr_repository_change_record_data* changeRecord2 =
+ reinterpret_cast<struct pldm_pdr_repository_change_record_data*>(
+ eventData->change_records +
+ PLDM_PDR_REPOSITORY_CHANGE_RECORD_MIN_LENGTH +
+ (changeRecordArr1.size() * sizeof(uint32_t)));
+ changeRecord2->event_data_operation = eventDataOperation2;
+ changeRecord2->number_of_change_entries = numberOfChangeEntries2;
+ memcpy(changeRecord2->change_entry, &changeRecordArr2[0],
+ changeRecordArr2.size() * sizeof(uint32_t));
+
+ uint8_t retEventDataFormat{};
+ uint8_t retNumberOfChangeRecords{};
+ size_t retChangeRecordDataOffset{0};
+ auto rc = decode_pldm_pdr_repository_chg_event_data(
+ reinterpret_cast<const uint8_t*>(eventData), eventDataArr.size(),
+ &retEventDataFormat, &retNumberOfChangeRecords,
+ &retChangeRecordDataOffset);
+ EXPECT_EQ(rc, PLDM_SUCCESS);
+ EXPECT_EQ(retEventDataFormat, FORMAT_IS_PDR_HANDLES);
+ EXPECT_EQ(retNumberOfChangeRecords, numberOfChangeRecords);
+
+ const uint8_t* changeRecordData =
+ reinterpret_cast<const uint8_t*>(changeRecord1);
+ size_t changeRecordDataSize =
+ eventDataArr.size() - PLDM_PDR_REPOSITORY_CHG_EVENT_MIN_LENGTH;
+ uint8_t retEventDataOperation;
+ uint8_t retNumberOfChangeEntries;
+ size_t retChangeEntryDataOffset;
+
+ rc = decode_pldm_pdr_repository_change_record_data(
+ reinterpret_cast<const uint8_t*>(changeRecordData),
+ changeRecordDataSize, &retEventDataOperation, &retNumberOfChangeEntries,
+ &retChangeEntryDataOffset);
+ EXPECT_EQ(rc, PLDM_SUCCESS);
+ EXPECT_EQ(retEventDataOperation, eventDataOperation1);
+ EXPECT_EQ(retNumberOfChangeEntries, numberOfChangeEntries1);
+ changeRecordData += retChangeEntryDataOffset;
+ EXPECT_EQ(0, memcmp(changeRecordData, &changeRecordArr1[0],
+ sizeof(uint32_t) * retNumberOfChangeEntries));
+
+ changeRecordData += sizeof(uint32_t) * retNumberOfChangeEntries;
+ changeRecordDataSize -= sizeof(uint32_t) * retNumberOfChangeEntries -
+ PLDM_PDR_REPOSITORY_CHANGE_RECORD_MIN_LENGTH;
+ rc = decode_pldm_pdr_repository_change_record_data(
+ reinterpret_cast<const uint8_t*>(changeRecordData),
+ changeRecordDataSize, &retEventDataOperation, &retNumberOfChangeEntries,
+ &retChangeEntryDataOffset);
+ EXPECT_EQ(rc, PLDM_SUCCESS);
+ EXPECT_EQ(retEventDataOperation, eventDataOperation2);
+ EXPECT_EQ(retNumberOfChangeEntries, numberOfChangeEntries2);
+ changeRecordData += retChangeEntryDataOffset;
+ EXPECT_EQ(0, memcmp(changeRecordData, &changeRecordArr2[0],
+ sizeof(uint32_t) * retNumberOfChangeEntries));
+}
+
+TEST(PldmPDRRepositoryChgEventEvent, testBadDecodeRequest)
+{
+ uint8_t eventDataFormat{};
+ uint8_t numberOfChangeRecords{};
+ size_t changeRecordDataOffset{};
+ auto rc = decode_pldm_pdr_repository_chg_event_data(
+ NULL, 0, &eventDataFormat, &numberOfChangeRecords,
+ &changeRecordDataOffset);
+ EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+ std::array<uint8_t, 2> eventData{};
+ rc = decode_pldm_pdr_repository_chg_event_data(
+ reinterpret_cast<const uint8_t*>(eventData.data()), 0, &eventDataFormat,
+ &numberOfChangeRecords, &changeRecordDataOffset);
+ EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+
+ uint8_t eventDataOperation{};
+ uint8_t numberOfChangeEntries{};
+ size_t changeEntryDataOffset{};
+ rc = decode_pldm_pdr_repository_change_record_data(
+ NULL, 0, &eventDataOperation, &numberOfChangeEntries,
+ &changeEntryDataOffset);
+ EXPECT_EQ(rc, PLDM_ERROR_INVALID_DATA);
+
+ std::array<uint8_t, 2> changeRecord{};
+ rc = decode_pldm_pdr_repository_change_record_data(
+ reinterpret_cast<const uint8_t*>(changeRecord.data()), 0,
+ &eventDataOperation, &numberOfChangeEntries, &changeEntryDataOffset);
+ EXPECT_EQ(rc, PLDM_ERROR_INVALID_LENGTH);
+}