/* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later */ #ifndef PLDM_MSGBUF_PLATFORM_H #define PLDM_MSGBUF_PLATFORM_H #include "../compiler.h" #include "../msgbuf.h" #include #include static inline int pldm_msgbuf_extract_value_pdr_hdr(struct pldm_msgbuf *ctx, struct pldm_value_pdr_hdr *hdr) { pldm_msgbuf_extract(ctx, hdr->record_handle); pldm_msgbuf_extract(ctx, hdr->version); pldm_msgbuf_extract(ctx, hdr->type); pldm_msgbuf_extract(ctx, hdr->record_change_num); pldm_msgbuf_extract(ctx, hdr->length); return pldm_msgbuf_validate(ctx); } LIBPLDM_CC_ALWAYS_INLINE int pldm_msgbuf_extract_sensor_data(struct pldm_msgbuf *ctx, enum pldm_sensor_readings_data_type tag, union_sensor_data_size *dst) { switch (tag) { case PLDM_SENSOR_DATA_SIZE_UINT8: return pldm_msgbuf_extract(ctx, dst->value_u8); case PLDM_SENSOR_DATA_SIZE_SINT8: return pldm_msgbuf_extract(ctx, dst->value_s8); case PLDM_SENSOR_DATA_SIZE_UINT16: return pldm_msgbuf_extract(ctx, dst->value_u16); case PLDM_SENSOR_DATA_SIZE_SINT16: return pldm_msgbuf_extract(ctx, dst->value_s16); case PLDM_SENSOR_DATA_SIZE_UINT32: return pldm_msgbuf_extract(ctx, dst->value_u32); case PLDM_SENSOR_DATA_SIZE_SINT32: return pldm_msgbuf_extract(ctx, dst->value_s32); } return -PLDM_ERROR_INVALID_DATA; } /* * This API is bad, but it's because the caller's APIs are also bad. They should * have used the approach used by callers of pldm_msgbuf_extract_sensor_data() * above */ LIBPLDM_CC_ALWAYS_INLINE int pldm_msgbuf_extract_sensor_value(struct pldm_msgbuf *ctx, enum pldm_sensor_readings_data_type tag, void *val) { switch (tag) { case PLDM_SENSOR_DATA_SIZE_UINT8: return pldm__msgbuf_extract_uint8(ctx, val); case PLDM_SENSOR_DATA_SIZE_SINT8: return pldm__msgbuf_extract_int8(ctx, val); case PLDM_SENSOR_DATA_SIZE_UINT16: return pldm__msgbuf_extract_uint16(ctx, val); case PLDM_SENSOR_DATA_SIZE_SINT16: return pldm__msgbuf_extract_int16(ctx, val); case PLDM_SENSOR_DATA_SIZE_UINT32: return pldm__msgbuf_extract_uint32(ctx, val); case PLDM_SENSOR_DATA_SIZE_SINT32: return pldm__msgbuf_extract_int32(ctx, val); } return -PLDM_ERROR_INVALID_DATA; } #define pldm_msgbuf_extract_range_field_format(ctx, tag, dst) \ pldm_msgbuf_extract_typecheck(union_range_field_format, \ pldm__msgbuf_extract_range_field_format, \ dst, ctx, tag, (void *)&(dst)) LIBPLDM_CC_ALWAYS_INLINE int pldm__msgbuf_extract_range_field_format( struct pldm_msgbuf *ctx, enum pldm_range_field_format tag, void *rff) { switch (tag) { case PLDM_RANGE_FIELD_FORMAT_UINT8: return pldm__msgbuf_extract_uint8( ctx, ((char *)rff) + offsetof(union_range_field_format, value_u8)); case PLDM_RANGE_FIELD_FORMAT_SINT8: return pldm__msgbuf_extract_int8( ctx, ((char *)rff) + offsetof(union_range_field_format, value_s8)); case PLDM_RANGE_FIELD_FORMAT_UINT16: return pldm__msgbuf_extract_uint16( ctx, ((char *)rff) + offsetof(union_range_field_format, value_u16)); case PLDM_RANGE_FIELD_FORMAT_SINT16: return pldm__msgbuf_extract_int16( ctx, ((char *)rff) + offsetof(union_range_field_format, value_s16)); case PLDM_RANGE_FIELD_FORMAT_UINT32: return pldm__msgbuf_extract_uint32( ctx, ((char *)rff) + offsetof(union_range_field_format, value_u32)); case PLDM_RANGE_FIELD_FORMAT_SINT32: return pldm__msgbuf_extract_int32( ctx, ((char *)rff) + offsetof(union_range_field_format, value_s32)); case PLDM_RANGE_FIELD_FORMAT_REAL32: return pldm__msgbuf_extract_real32( ctx, ((char *)rff) + offsetof(union_range_field_format, value_f32)); } return -PLDM_ERROR_INVALID_DATA; } /* This API is bad, but it's because the caller's APIs are also bad */ LIBPLDM_CC_ALWAYS_INLINE int pldm_msgbuf_extract_effecter_value(struct pldm_msgbuf *ctx, enum pldm_effecter_data_size tag, void *dst) { switch (tag) { case PLDM_EFFECTER_DATA_SIZE_UINT8: return pldm__msgbuf_extract_uint8(ctx, dst); case PLDM_EFFECTER_DATA_SIZE_SINT8: return pldm__msgbuf_extract_int8(ctx, dst); case PLDM_EFFECTER_DATA_SIZE_UINT16: return pldm__msgbuf_extract_uint16(ctx, dst); case PLDM_EFFECTER_DATA_SIZE_SINT16: return pldm__msgbuf_extract_int16(ctx, dst); case PLDM_EFFECTER_DATA_SIZE_UINT32: return pldm__msgbuf_extract_uint32(ctx, dst); case PLDM_EFFECTER_DATA_SIZE_SINT32: return pldm__msgbuf_extract_int32(ctx, dst); } return -PLDM_ERROR_INVALID_DATA; } #define pldm_msgbuf_extract_effecter_data(ctx, tag, dst) \ pldm_msgbuf_extract_typecheck(union_effecter_data_size, \ pldm__msgbuf_extract_range_field_format, \ dst, ctx, tag, (void *)&(dst)) LIBPLDM_CC_ALWAYS_INLINE int pldm__msgbuf_extract_effecter_data(struct pldm_msgbuf *ctx, enum pldm_effecter_data_size tag, void *ed) { switch (tag) { case PLDM_EFFECTER_DATA_SIZE_UINT8: return pldm__msgbuf_extract_uint8( ctx, ((char *)ed) + offsetof(union_effecter_data_size, value_u8)); case PLDM_EFFECTER_DATA_SIZE_SINT8: return pldm__msgbuf_extract_int8( ctx, ((char *)ed) + offsetof(union_effecter_data_size, value_s8)); case PLDM_EFFECTER_DATA_SIZE_UINT16: return pldm__msgbuf_extract_uint16( ctx, ((char *)ed) + offsetof(union_effecter_data_size, value_u16)); case PLDM_EFFECTER_DATA_SIZE_SINT16: return pldm__msgbuf_extract_int16( ctx, ((char *)ed) + offsetof(union_effecter_data_size, value_s16)); case PLDM_EFFECTER_DATA_SIZE_UINT32: return pldm__msgbuf_extract_uint32( ctx, ((char *)ed) + offsetof(union_effecter_data_size, value_u32)); case PLDM_EFFECTER_DATA_SIZE_SINT32: return pldm__msgbuf_extract_int32( ctx, ((char *)ed) + offsetof(union_effecter_data_size, value_s32)); } return -PLDM_ERROR_INVALID_DATA; } #ifdef __cplusplus #include template static inline int pldm_msgbuf_typecheck_range_field_format( struct pldm_msgbuf *ctx, enum pldm_range_field_format tag, void *_rff) { static_assert(std::is_same::value); return pldm__msgbuf_extract_range_field_format(ctx, tag, _rff); } #endif #endif