1 /* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later */ 2 #ifndef PLDM_MSGBUF_PLATFORM_H 3 #define PLDM_MSGBUF_PLATFORM_H 4 5 #include "../compiler.h" 6 #include "../msgbuf.h" 7 #include <libpldm/base.h> 8 #include <libpldm/platform.h> 9 10 static inline int 11 pldm_msgbuf_extract_value_pdr_hdr(struct pldm_msgbuf *ctx, 12 struct pldm_value_pdr_hdr *hdr) 13 { 14 pldm_msgbuf_extract(ctx, hdr->record_handle); 15 pldm_msgbuf_extract(ctx, hdr->version); 16 pldm_msgbuf_extract(ctx, hdr->type); 17 pldm_msgbuf_extract(ctx, hdr->record_change_num); 18 pldm_msgbuf_extract(ctx, hdr->length); 19 20 return pldm_msgbuf_validate(ctx); 21 } 22 23 LIBPLDM_CC_ALWAYS_INLINE int 24 pldm_msgbuf_extract_sensor_data(struct pldm_msgbuf *ctx, 25 enum pldm_sensor_readings_data_type tag, 26 union_sensor_data_size *dst) 27 { 28 switch (tag) { 29 case PLDM_SENSOR_DATA_SIZE_UINT8: 30 return pldm_msgbuf_extract(ctx, dst->value_u8); 31 case PLDM_SENSOR_DATA_SIZE_SINT8: 32 return pldm_msgbuf_extract(ctx, dst->value_s8); 33 case PLDM_SENSOR_DATA_SIZE_UINT16: 34 return pldm_msgbuf_extract(ctx, dst->value_u16); 35 case PLDM_SENSOR_DATA_SIZE_SINT16: 36 return pldm_msgbuf_extract(ctx, dst->value_s16); 37 case PLDM_SENSOR_DATA_SIZE_UINT32: 38 return pldm_msgbuf_extract(ctx, dst->value_u32); 39 case PLDM_SENSOR_DATA_SIZE_SINT32: 40 return pldm_msgbuf_extract(ctx, dst->value_s32); 41 } 42 43 return -PLDM_ERROR_INVALID_DATA; 44 } 45 46 /* 47 * This API is bad, but it's because the caller's APIs are also bad. They should 48 * have used the approach used by callers of pldm_msgbuf_extract_sensor_data() 49 * above 50 */ 51 LIBPLDM_CC_ALWAYS_INLINE int 52 pldm_msgbuf_extract_sensor_value(struct pldm_msgbuf *ctx, 53 enum pldm_sensor_readings_data_type tag, 54 void *val) 55 { 56 switch (tag) { 57 case PLDM_SENSOR_DATA_SIZE_UINT8: 58 return pldm__msgbuf_extract_uint8(ctx, val); 59 case PLDM_SENSOR_DATA_SIZE_SINT8: 60 return pldm__msgbuf_extract_int8(ctx, val); 61 case PLDM_SENSOR_DATA_SIZE_UINT16: 62 return pldm__msgbuf_extract_uint16(ctx, val); 63 case PLDM_SENSOR_DATA_SIZE_SINT16: 64 return pldm__msgbuf_extract_int16(ctx, val); 65 case PLDM_SENSOR_DATA_SIZE_UINT32: 66 return pldm__msgbuf_extract_uint32(ctx, val); 67 case PLDM_SENSOR_DATA_SIZE_SINT32: 68 return pldm__msgbuf_extract_int32(ctx, val); 69 } 70 71 return -PLDM_ERROR_INVALID_DATA; 72 } 73 74 #define pldm_msgbuf_extract_range_field_format(ctx, tag, dst) \ 75 pldm_msgbuf_extract_typecheck(union_range_field_format, \ 76 pldm__msgbuf_extract_range_field_format, \ 77 dst, ctx, tag, (void *)&(dst)) 78 LIBPLDM_CC_ALWAYS_INLINE int pldm__msgbuf_extract_range_field_format( 79 struct pldm_msgbuf *ctx, enum pldm_range_field_format tag, void *rff) 80 { 81 switch (tag) { 82 case PLDM_RANGE_FIELD_FORMAT_UINT8: 83 return pldm__msgbuf_extract_uint8( 84 ctx, ((char *)rff) + offsetof(union_range_field_format, 85 value_u8)); 86 case PLDM_RANGE_FIELD_FORMAT_SINT8: 87 return pldm__msgbuf_extract_int8( 88 ctx, ((char *)rff) + offsetof(union_range_field_format, 89 value_s8)); 90 case PLDM_RANGE_FIELD_FORMAT_UINT16: 91 return pldm__msgbuf_extract_uint16( 92 ctx, ((char *)rff) + offsetof(union_range_field_format, 93 value_u16)); 94 case PLDM_RANGE_FIELD_FORMAT_SINT16: 95 return pldm__msgbuf_extract_int16( 96 ctx, ((char *)rff) + offsetof(union_range_field_format, 97 value_s16)); 98 case PLDM_RANGE_FIELD_FORMAT_UINT32: 99 return pldm__msgbuf_extract_uint32( 100 ctx, ((char *)rff) + offsetof(union_range_field_format, 101 value_u32)); 102 case PLDM_RANGE_FIELD_FORMAT_SINT32: 103 return pldm__msgbuf_extract_int32( 104 ctx, ((char *)rff) + offsetof(union_range_field_format, 105 value_s32)); 106 case PLDM_RANGE_FIELD_FORMAT_REAL32: 107 return pldm__msgbuf_extract_real32( 108 ctx, ((char *)rff) + offsetof(union_range_field_format, 109 value_f32)); 110 } 111 112 return -PLDM_ERROR_INVALID_DATA; 113 } 114 115 /* This API is bad, but it's because the caller's APIs are also bad */ 116 LIBPLDM_CC_ALWAYS_INLINE int 117 pldm_msgbuf_extract_effecter_value(struct pldm_msgbuf *ctx, 118 enum pldm_effecter_data_size tag, void *dst) 119 { 120 switch (tag) { 121 case PLDM_EFFECTER_DATA_SIZE_UINT8: 122 return pldm__msgbuf_extract_uint8(ctx, dst); 123 case PLDM_EFFECTER_DATA_SIZE_SINT8: 124 return pldm__msgbuf_extract_int8(ctx, dst); 125 case PLDM_EFFECTER_DATA_SIZE_UINT16: 126 return pldm__msgbuf_extract_uint16(ctx, dst); 127 case PLDM_EFFECTER_DATA_SIZE_SINT16: 128 return pldm__msgbuf_extract_int16(ctx, dst); 129 case PLDM_EFFECTER_DATA_SIZE_UINT32: 130 return pldm__msgbuf_extract_uint32(ctx, dst); 131 case PLDM_EFFECTER_DATA_SIZE_SINT32: 132 return pldm__msgbuf_extract_int32(ctx, dst); 133 } 134 135 return -PLDM_ERROR_INVALID_DATA; 136 } 137 138 #define pldm_msgbuf_extract_effecter_data(ctx, tag, dst) \ 139 pldm_msgbuf_extract_typecheck(union_effecter_data_size, \ 140 pldm__msgbuf_extract_range_field_format, \ 141 dst, ctx, tag, (void *)&(dst)) 142 LIBPLDM_CC_ALWAYS_INLINE int 143 pldm__msgbuf_extract_effecter_data(struct pldm_msgbuf *ctx, 144 enum pldm_effecter_data_size tag, void *ed) 145 { 146 switch (tag) { 147 case PLDM_EFFECTER_DATA_SIZE_UINT8: 148 return pldm__msgbuf_extract_uint8( 149 ctx, ((char *)ed) + offsetof(union_effecter_data_size, 150 value_u8)); 151 case PLDM_EFFECTER_DATA_SIZE_SINT8: 152 return pldm__msgbuf_extract_int8( 153 ctx, ((char *)ed) + offsetof(union_effecter_data_size, 154 value_s8)); 155 case PLDM_EFFECTER_DATA_SIZE_UINT16: 156 return pldm__msgbuf_extract_uint16( 157 ctx, ((char *)ed) + offsetof(union_effecter_data_size, 158 value_u16)); 159 case PLDM_EFFECTER_DATA_SIZE_SINT16: 160 return pldm__msgbuf_extract_int16( 161 ctx, ((char *)ed) + offsetof(union_effecter_data_size, 162 value_s16)); 163 case PLDM_EFFECTER_DATA_SIZE_UINT32: 164 return pldm__msgbuf_extract_uint32( 165 ctx, ((char *)ed) + offsetof(union_effecter_data_size, 166 value_u32)); 167 case PLDM_EFFECTER_DATA_SIZE_SINT32: 168 return pldm__msgbuf_extract_int32( 169 ctx, ((char *)ed) + offsetof(union_effecter_data_size, 170 value_s32)); 171 } 172 173 return -PLDM_ERROR_INVALID_DATA; 174 } 175 176 #ifdef __cplusplus 177 #include <type_traits> 178 179 template <typename T> 180 static inline int pldm_msgbuf_typecheck_range_field_format( 181 struct pldm_msgbuf *ctx, enum pldm_range_field_format tag, void *_rff) 182 { 183 static_assert(std::is_same<union_range_field_format, T>::value); 184 return pldm__msgbuf_extract_range_field_format(ctx, tag, _rff); 185 } 186 #endif 187 188 #endif 189