Add encoders for state sensor/effecter PDRs and sensor event data
Change-Id: I736d1b7b1c124faf8fbf86bb3b760cc9b48c1e2b
Signed-off-by: Zach Clark <zach@ibm.com>
diff --git a/libpldm/base.h b/libpldm/base.h
index dd63f1c..5109c34 100644
--- a/libpldm/base.h
+++ b/libpldm/base.h
@@ -110,6 +110,10 @@
uint8_t command; //!< PLDM command code
} __attribute__((packed));
+// Macros for byte-swapping variables in-place
+#define HTOLE32(X) (X = htole32(X))
+#define HTOLE16(X) (X = htole16(X))
+
/** @struct pldm_msg
*
* Structure representing PLDM message
diff --git a/libpldm/platform.c b/libpldm/platform.c
index 9b0403f..401e1ca 100644
--- a/libpldm/platform.c
+++ b/libpldm/platform.c
@@ -3,6 +3,140 @@
#include "platform.h"
+int encode_state_effecter_pdr(
+ struct pldm_state_effecter_pdr *const effecter,
+ const size_t allocation_size,
+ const struct state_effecter_possible_states *const possible_states,
+ const size_t possible_states_size, size_t *const actual_size)
+{
+ // Encode possible states
+
+ size_t calculated_possible_states_size = 0;
+
+ {
+ char *states_ptr = (char *)possible_states;
+ char *const begin_states_ptr = states_ptr;
+
+ for (int i = 0; i < effecter->composite_effecter_count; ++i) {
+ struct state_effecter_possible_states *states =
+ (struct state_effecter_possible_states *)states_ptr;
+
+ HTOLE16(states->state_set_id);
+
+ states_ptr +=
+ (sizeof(*states) - sizeof(states->states) +
+ states->possible_states_size);
+ }
+
+ calculated_possible_states_size = states_ptr - begin_states_ptr;
+ }
+
+ // Check lengths
+
+ if (possible_states_size != calculated_possible_states_size) {
+ *actual_size = 0;
+ return PLDM_ERROR;
+ }
+
+ *actual_size =
+ (sizeof(struct pldm_state_effecter_pdr) + possible_states_size -
+ sizeof(effecter->possible_states));
+
+ if (allocation_size < *actual_size) {
+ *actual_size = 0;
+ return PLDM_ERROR_INVALID_LENGTH;
+ }
+
+ // Encode rest of PDR
+
+ effecter->hdr.version = 1;
+ effecter->hdr.type = PLDM_STATE_EFFECTER_PDR;
+ effecter->hdr.length = *actual_size - sizeof(struct pldm_pdr_hdr);
+
+ memcpy(effecter->possible_states, possible_states,
+ possible_states_size);
+
+ // Convert effecter PDR body
+ HTOLE16(effecter->terminus_handle);
+ HTOLE16(effecter->effecter_id);
+ HTOLE16(effecter->entity_type);
+ HTOLE16(effecter->entity_instance);
+ HTOLE16(effecter->container_id);
+ HTOLE16(effecter->effecter_semantic_id);
+
+ // Convert header
+ HTOLE32(effecter->hdr.record_handle);
+ HTOLE16(effecter->hdr.record_change_num);
+ HTOLE16(effecter->hdr.length);
+
+ return PLDM_SUCCESS;
+}
+
+int encode_state_sensor_pdr(
+ struct pldm_state_sensor_pdr *const sensor, const size_t allocation_size,
+ const struct state_sensor_possible_states *const possible_states,
+ const size_t possible_states_size, size_t *const actual_size)
+{
+ // Encode possible states
+
+ size_t calculated_possible_states_size = 0;
+
+ {
+ char *states_ptr = (char *)possible_states,
+ *const begin_states_ptr = states_ptr;
+
+ for (int i = 0; i < sensor->composite_sensor_count; ++i) {
+ struct state_sensor_possible_states *states =
+ (struct state_sensor_possible_states *)states_ptr;
+
+ HTOLE16(states->state_set_id);
+
+ states_ptr +=
+ (sizeof(*states) - sizeof(states->states) +
+ states->possible_states_size);
+ }
+
+ calculated_possible_states_size = states_ptr - begin_states_ptr;
+ }
+
+ // Check lengths
+
+ if (possible_states_size != calculated_possible_states_size) {
+ *actual_size = 0;
+ return PLDM_ERROR;
+ }
+
+ *actual_size = (sizeof(struct pldm_state_sensor_pdr) +
+ possible_states_size - sizeof(sensor->possible_states));
+
+ if (allocation_size < *actual_size) {
+ *actual_size = 0;
+ return PLDM_ERROR_INVALID_LENGTH;
+ }
+
+ // Encode rest of PDR
+
+ sensor->hdr.version = 1;
+ sensor->hdr.type = PLDM_STATE_SENSOR_PDR;
+ sensor->hdr.length = *actual_size - sizeof(struct pldm_pdr_hdr);
+
+ memcpy(sensor->possible_states, possible_states, possible_states_size);
+
+ // Convert sensor PDR body
+ HTOLE16(sensor->terminus_handle);
+ HTOLE16(sensor->sensor_id);
+ HTOLE16(sensor->entity_type);
+ HTOLE16(sensor->entity_instance);
+ HTOLE16(sensor->container_id);
+
+ // Convert header
+ HTOLE32(sensor->hdr.record_handle);
+ HTOLE16(sensor->hdr.record_change_num);
+ HTOLE16(sensor->hdr.length);
+
+ return PLDM_SUCCESS;
+}
+
int encode_set_state_effecter_states_resp(uint8_t instance_id,
uint8_t completion_code,
struct pldm_msg *msg)
@@ -562,6 +696,40 @@
return PLDM_SUCCESS;
}
+int encode_sensor_event_data(
+ struct pldm_sensor_event_data *const event_data,
+ const size_t event_data_size, const uint16_t sensor_id,
+ const enum sensor_event_class_states sensor_event_class,
+ const uint8_t sensor_offset, const uint8_t event_state,
+ const uint8_t previous_event_state, size_t *const actual_event_data_size)
+{
+ *actual_event_data_size =
+ (sizeof(*event_data) - sizeof(event_data->event_class) +
+ sizeof(struct pldm_sensor_event_state_sensor_state));
+
+ if (!event_data) {
+ return PLDM_SUCCESS;
+ }
+
+ if (event_data_size < *actual_event_data_size) {
+ *actual_event_data_size = 0;
+ return PLDM_ERROR_INVALID_LENGTH;
+ }
+
+ event_data->sensor_id = htole32(sensor_id);
+ event_data->sensor_event_class_type = sensor_event_class;
+
+ struct pldm_sensor_event_state_sensor_state *const state_data =
+ (struct pldm_sensor_event_state_sensor_state *)
+ event_data->event_class;
+
+ state_data->sensor_offset = sensor_offset;
+ state_data->event_state = event_state;
+ state_data->previous_event_state = previous_event_state;
+
+ return PLDM_SUCCESS;
+}
+
int decode_platform_event_message_req(const struct pldm_msg *msg,
size_t payload_length,
uint8_t *format_version, uint8_t *tid,
diff --git a/libpldm/platform.h b/libpldm/platform.h
index 5d80511..be55d4f 100644
--- a/libpldm/platform.h
+++ b/libpldm/platform.h
@@ -316,6 +316,29 @@
uint8_t possible_states[1];
} __attribute__((packed));
+/** @brief Encode PLDM state sensor PDR
+ *
+ * @param[in/out] sensor Structure to encode. All members of
+ * sensor, except those mentioned in the @note below, should be initialized by
+ * the caller.
+ * @param[in] allocation_size Size of sensor allocation in bytes
+ * @param[in] possible_states Possible sensor states
+ * @param[in] possible_states_size Size of possible sensor states in bytes
+ * @param[out] actual_size Size of sensor PDR. Set to 0 on error.
+ * @return int pldm_completion_codes
+ * PLDM_SUCCESS/PLDM_ERROR/PLDM_ERROR_INVALID_LENGTH
+ *
+ * @note The sensor parameter will be encoded in place.
+ * @note Caller is responsible for allocation of the sensor parameter. Caller
+ * must allocate enough space for the base structure and the
+ * sensor->possible_states array, otherwise the function will fail.
+ * @note sensor->hdr.length, .type, and .version will be set appropriately.
+ */
+int encode_state_sensor_pdr(
+ struct pldm_state_sensor_pdr *sensor, size_t allocation_size,
+ const struct state_sensor_possible_states *possible_states,
+ size_t possible_states_size, size_t *actual_size);
+
/** @union union_effecter_data_size
*
* The bit width and format of reading and threshold values that the effecter
@@ -399,6 +422,32 @@
bitfield8_t states[1];
} __attribute__((packed));
+/** @brief Encode PLDM state effecter PDR
+ *
+ * @param[in/out] effecter Structure to encode. All members of
+ * effecter, except those mentioned in
+ * the @note below, should be initialized
+ * by the caller.
+ * @param[in] allocation_size Size of effecter allocation in bytes
+ * @param[in] possible_states Possible effecter states
+ * @param[in] possible_states_size Size of possible effecter states in
+ * bytes
+ * @param[out] actual_size Size of effecter PDR. Set to 0 on
+ * error.
+ * @return int pldm_completion_codes
+ * PLDM_SUCCESS/PLDM_ERROR/PLDM_ERROR_INVALID_LENGTH
+ *
+ * @note The effecter parameter will be encoded in place.
+ * @note Caller is responsible for allocation of the effecter parameter. Caller
+ * must allocate enough space for the base structure and the
+ * effecter->possible_states array, otherwise the function will fail.
+ * @note effecter->hdr.length, .type, and .version will be set appropriately.
+ */
+int encode_state_effecter_pdr(
+ struct pldm_state_effecter_pdr *effecter, size_t allocation_size,
+ const struct state_effecter_possible_states *possible_states,
+ size_t possible_states_size, size_t *actual_size);
+
/** @struct set_effecter_state_field
*
* Structure representing a stateField in SetStateEffecterStates command */
@@ -1273,6 +1322,29 @@
struct pldm_pdr_repository_chg_event_data *event_data,
size_t *actual_change_records_size, size_t max_change_records_size);
+/** @brief Encode event data for a PLDM Sensor Event
+ *
+ * @param[out] event_data The object to store the encoded event in
+ * @param[in] event_data_size Size of the allocation for event_data
+ * @param[in] sensor_id Sensor ID
+ * @param[in] sensor_event_class Sensor event class
+ * @param[in] sensor_offset Offset
+ * @param[in] event_state Event state
+ * @param[in] previous_event_state Previous event state
+ * @param[out] actual_event_data_size The real size in bytes of the event_data
+ * @return int pldm_completion_codes PLDM_SUCCESS/PLDM_ERROR_INVALID_LENGTH
+ * @note If event_data is NULL, then *actual_event_data_size will be set to
+ * reflect the size of the event data, and PLDM_SUCCESS will be returned.
+ * @note The caller is responsible for allocating and deallocating the
+ * event_data
+ */
+int encode_sensor_event_data(struct pldm_sensor_event_data *event_data,
+ size_t event_data_size, uint16_t sensor_id,
+ enum sensor_event_class_states sensor_event_class,
+ uint8_t sensor_offset, uint8_t event_state,
+ uint8_t previous_event_state,
+ size_t *actual_event_data_size);
+
/** @brief Decode PldmPDRRepositoryChangeRecord response data
*
* @param[in] change_record_data - changeRecordData for
diff --git a/libpldm/state_set.h b/libpldm/state_set.h
index 90a128e..7bc364c 100644
--- a/libpldm/state_set.h
+++ b/libpldm/state_set.h
@@ -127,8 +127,31 @@
PLDM_STATE_SET_SLOT_STATE = 353,
};
+/* @brief List of states for the Boot Restart Cause state set (ID 192).
+ */
+enum pldm_state_set_boot_restart_cause_values {
+ PLDM_STATE_SET_BOOT_RESTART_CAUSE_POWERED_UP = 1,
+ PLDM_STATE_SET_BOOT_RESTART_CAUSE_HARD_RESET = 2,
+ PLDM_STATE_SET_BOOT_RESTART_CAUSE_WARM_RESET = 3,
+ PLDM_STATE_SET_BOOT_RESTART_CAUSE_MANUAL_HARD_RESET = 4,
+ PLDM_STATE_SET_BOOT_RESTART_CAUSE_MANUAL_WARM_RESET = 5,
+ PLDM_STATE_SET_BOOT_RESTART_CAUSE_SYSTEM_RESTART = 6,
+ PLDM_STATE_SET_BOOT_RESTART_CAUSE_WATCHDOG_TIMEOUT = 7
+};
+
+/* @brief List of states for the Operational Running Status state set (ID 11).
+ */
+enum pldm_state_set_operational_running_status_values {
+ PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS_STARTING = 1,
+ PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS_STOPPING = 2,
+ PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS_STOPPED = 3,
+ PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS_IN_SERVICE = 4,
+ PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS_ABORTED = 5,
+ PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS_DORMANT = 6
+};
+
#ifdef __cplusplus
}
#endif
-#endif /* STATE_SET_H */
\ No newline at end of file
+#endif /* STATE_SET_H */