1 /*
2 * Copyright (C) 2003-2015 FreeIPMI Core Team
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 */
18
19 #ifdef HAVE_CONFIG_H
20 #include "config.h"
21 #endif /* HAVE_CONFIG_H */
22
23 #include <stdio.h>
24 #include <stdlib.h>
25 #if STDC_HEADERS
26 #include <string.h>
27 #endif /* STDC_HEADERS */
28 #if HAVE_UNISTD_H
29 #include <unistd.h>
30 #endif /* HAVE_UNISTD_H */
31 #include <assert.h>
32 #include <errno.h>
33
34 #include "freeipmi/sdr/ipmi-sdr.h"
35
36 #include "freeipmi/fiid/fiid.h"
37 #include "freeipmi/record-format/ipmi-sdr-record-format.h"
38 #include "freeipmi/spec/ipmi-sensor-units-spec.h"
39 #include "freeipmi/spec/ipmi-event-reading-type-code-spec.h"
40 #include "freeipmi/util/ipmi-sensor-util.h"
41
42 #include "ipmi-sdr-common.h"
43 #include "ipmi-sdr-defs.h"
44 #include "ipmi-sdr-trace.h"
45 #include "ipmi-sdr-util.h"
46
47 #include "libcommon/ipmi-fiid-util.h"
48
49 #include "freeipmi-portability.h"
50
51 #define IPMI_SDR_PARSE_RECORD_TYPE_FULL_SENSOR_RECORD 0x0001
52 #define IPMI_SDR_PARSE_RECORD_TYPE_COMPACT_SENSOR_RECORD 0x0002
53 #define IPMI_SDR_PARSE_RECORD_TYPE_EVENT_ONLY_RECORD 0x0004
54 #define IPMI_SDR_PARSE_RECORD_TYPE_ENTITY_ASSOCIATION_RECORD 0x0008
55 #define IPMI_SDR_PARSE_RECORD_TYPE_DEVICE_RELATIVE_ENTITY_ASSOCIATION_RECORD 0x0010
56 #define IPMI_SDR_PARSE_RECORD_TYPE_GENERIC_DEVICE_LOCATOR_RECORD 0x0020
57 #define IPMI_SDR_PARSE_RECORD_TYPE_FRU_DEVICE_LOCATOR_RECORD 0x0040
58 #define IPMI_SDR_PARSE_RECORD_TYPE_MANAGEMENT_CONTROLLER_DEVICE_LOCATOR_RECORD 0x0080
59 #define IPMI_SDR_PARSE_RECORD_TYPE_MANAGEMENT_CONTROLLER_CONFIRMATION_RECORD 0x0100
60 #define IPMI_SDR_PARSE_RECORD_TYPE_BMC_MESSAGE_CHANNEL_INFO_RECORD 0x0200
61 #define IPMI_SDR_PARSE_RECORD_TYPE_OEM_RECORD 0x0400
62
63 int
ipmi_sdr_parse_record_id_and_type(ipmi_sdr_ctx_t ctx,const void * sdr_record,unsigned int sdr_record_len,uint16_t * record_id,uint8_t * record_type)64 ipmi_sdr_parse_record_id_and_type (ipmi_sdr_ctx_t ctx,
65 const void *sdr_record,
66 unsigned int sdr_record_len,
67 uint16_t *record_id,
68 uint8_t *record_type)
69 {
70 uint8_t sdr_record_buf[IPMI_SDR_MAX_RECORD_LENGTH];
71 int sdr_record_buf_len;
72 fiid_obj_t obj_sdr_record_header = NULL;
73 int sdr_record_header_len;
74 void *sdr_record_to_use;
75 unsigned int sdr_record_len_to_use;
76 uint64_t val;
77 int rv = -1;
78
79 if (!ctx || ctx->magic != IPMI_SDR_CTX_MAGIC)
80 {
81 ERR_TRACE (ipmi_sdr_ctx_errormsg (ctx), ipmi_sdr_ctx_errnum (ctx));
82 return (-1);
83 }
84
85 if (!sdr_record || !sdr_record_len)
86 {
87 if (ctx->operation == IPMI_SDR_OPERATION_READ_CACHE
88 && !sdr_record
89 && !sdr_record_len)
90 {
91 if ((sdr_record_buf_len = ipmi_sdr_cache_record_read (ctx,
92 sdr_record_buf,
93 IPMI_SDR_MAX_RECORD_LENGTH)) < 0)
94 {
95 SDR_SET_INTERNAL_ERRNUM (ctx);
96 return (-1);
97 }
98 sdr_record_to_use = sdr_record_buf;
99 sdr_record_len_to_use = sdr_record_buf_len;
100 }
101 else
102 {
103 SDR_SET_ERRNUM (ctx, IPMI_SDR_ERR_PARAMETERS);
104 return (-1);
105 }
106 }
107 else
108 {
109 sdr_record_to_use = (void *)sdr_record;
110 sdr_record_len_to_use = sdr_record_len;
111 }
112
113 if ((sdr_record_header_len = fiid_template_len_bytes (tmpl_sdr_record_header)) < 0)
114 {
115 SDR_ERRNO_TO_SDR_ERRNUM (ctx, errno);
116 goto cleanup;
117 }
118
119 if (sdr_record_len_to_use < sdr_record_header_len)
120 {
121 SDR_SET_ERRNUM (ctx, IPMI_SDR_ERR_PARSE_INCOMPLETE_SDR_RECORD);
122 goto cleanup;
123 }
124
125 if (!(obj_sdr_record_header = fiid_obj_create (tmpl_sdr_record_header)))
126 {
127 SDR_ERRNO_TO_SDR_ERRNUM (ctx, errno);
128 goto cleanup;
129 }
130
131 if (fiid_obj_set_all (obj_sdr_record_header,
132 sdr_record_to_use,
133 sdr_record_header_len) < 0)
134 {
135 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record_header);
136 goto cleanup;
137 }
138
139 if (record_id)
140 {
141 if (FIID_OBJ_GET (obj_sdr_record_header,
142 "record_id",
143 &val) < 0)
144 {
145 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record_header);
146 goto cleanup;
147 }
148 *record_id = val;
149 }
150
151 if (record_type)
152 {
153 if (FIID_OBJ_GET (obj_sdr_record_header,
154 "record_type",
155 &val) < 0)
156 {
157 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record_header);
158 goto cleanup;
159 }
160 *record_type = val;
161 }
162
163 sdr_check_read_status (ctx);
164
165 rv = 0;
166 ctx->errnum = IPMI_SDR_ERR_SUCCESS;
167 cleanup:
168 fiid_obj_destroy (obj_sdr_record_header);
169 return (rv);
170 }
171
172 static fiid_obj_t
_sdr_record_get_common(ipmi_sdr_ctx_t ctx,const void * sdr_record,unsigned int sdr_record_len,uint32_t acceptable_record_types)173 _sdr_record_get_common (ipmi_sdr_ctx_t ctx,
174 const void *sdr_record,
175 unsigned int sdr_record_len,
176 uint32_t acceptable_record_types)
177 {
178 uint8_t sdr_record_buf[IPMI_SDR_MAX_RECORD_LENGTH];
179 int sdr_record_buf_len;
180 void *sdr_record_to_use;
181 unsigned int sdr_record_len_to_use;
182 fiid_obj_t obj_sdr_record = NULL;
183 uint8_t record_type;
184
185 assert (acceptable_record_types);
186
187 if (!ctx || ctx->magic != IPMI_SDR_CTX_MAGIC)
188 {
189 ERR_TRACE (ipmi_sdr_ctx_errormsg (ctx), ipmi_sdr_ctx_errnum (ctx));
190 goto cleanup;
191 }
192
193 if (!sdr_record || !sdr_record_len)
194 {
195 if (ctx->operation == IPMI_SDR_OPERATION_READ_CACHE
196 && !sdr_record
197 && !sdr_record_len)
198 {
199 if ((sdr_record_buf_len = ipmi_sdr_cache_record_read (ctx,
200 sdr_record_buf,
201 IPMI_SDR_MAX_RECORD_LENGTH)) < 0)
202 {
203 SDR_SET_INTERNAL_ERRNUM (ctx);
204 goto cleanup;
205 }
206 sdr_record_to_use = sdr_record_buf;
207 sdr_record_len_to_use = sdr_record_buf_len;
208 }
209 else
210 {
211 SDR_SET_ERRNUM (ctx, IPMI_SDR_ERR_PARAMETERS);
212 goto cleanup;
213 }
214 }
215 else
216 {
217 sdr_record_to_use = (void *)sdr_record;
218 sdr_record_len_to_use = sdr_record_len;
219 }
220
221 if (ipmi_sdr_parse_record_id_and_type (ctx,
222 sdr_record_to_use,
223 sdr_record_len_to_use,
224 NULL,
225 &record_type) < 0)
226 {
227 SDR_SET_INTERNAL_ERRNUM (ctx);
228 goto cleanup;
229 }
230
231 if (!(((acceptable_record_types & IPMI_SDR_PARSE_RECORD_TYPE_FULL_SENSOR_RECORD)
232 && record_type == IPMI_SDR_FORMAT_FULL_SENSOR_RECORD)
233 || ((acceptable_record_types & IPMI_SDR_PARSE_RECORD_TYPE_COMPACT_SENSOR_RECORD)
234 && record_type == IPMI_SDR_FORMAT_COMPACT_SENSOR_RECORD)
235 || ((acceptable_record_types & IPMI_SDR_PARSE_RECORD_TYPE_EVENT_ONLY_RECORD)
236 && record_type == IPMI_SDR_FORMAT_EVENT_ONLY_RECORD)
237 || ((acceptable_record_types & IPMI_SDR_PARSE_RECORD_TYPE_ENTITY_ASSOCIATION_RECORD)
238 && record_type == IPMI_SDR_FORMAT_ENTITY_ASSOCIATION_RECORD)
239 || ((acceptable_record_types & IPMI_SDR_PARSE_RECORD_TYPE_DEVICE_RELATIVE_ENTITY_ASSOCIATION_RECORD)
240 && record_type == IPMI_SDR_FORMAT_DEVICE_RELATIVE_ENTITY_ASSOCIATION_RECORD)
241
242 || ((acceptable_record_types & IPMI_SDR_PARSE_RECORD_TYPE_GENERIC_DEVICE_LOCATOR_RECORD)
243 && record_type == IPMI_SDR_FORMAT_GENERIC_DEVICE_LOCATOR_RECORD)
244 || ((acceptable_record_types & IPMI_SDR_PARSE_RECORD_TYPE_FRU_DEVICE_LOCATOR_RECORD)
245 && record_type == IPMI_SDR_FORMAT_FRU_DEVICE_LOCATOR_RECORD)
246 || ((acceptable_record_types & IPMI_SDR_PARSE_RECORD_TYPE_MANAGEMENT_CONTROLLER_DEVICE_LOCATOR_RECORD)
247 && record_type == IPMI_SDR_FORMAT_MANAGEMENT_CONTROLLER_DEVICE_LOCATOR_RECORD)
248 || ((acceptable_record_types & IPMI_SDR_PARSE_RECORD_TYPE_MANAGEMENT_CONTROLLER_CONFIRMATION_RECORD)
249 && record_type == IPMI_SDR_FORMAT_MANAGEMENT_CONTROLLER_CONFIRMATION_RECORD)
250 || ((acceptable_record_types & IPMI_SDR_PARSE_RECORD_TYPE_BMC_MESSAGE_CHANNEL_INFO_RECORD)
251 && record_type == IPMI_SDR_FORMAT_BMC_MESSAGE_CHANNEL_INFO_RECORD)
252 || ((acceptable_record_types & IPMI_SDR_PARSE_RECORD_TYPE_OEM_RECORD)
253 && record_type == IPMI_SDR_FORMAT_OEM_RECORD)
254 ))
255 {
256 SDR_SET_ERRNUM (ctx, IPMI_SDR_ERR_PARSE_INVALID_SDR_RECORD);
257 goto cleanup;
258 }
259
260 if (record_type == IPMI_SDR_FORMAT_FULL_SENSOR_RECORD)
261 {
262 if (!(obj_sdr_record = fiid_obj_create (tmpl_sdr_full_sensor_record)))
263 {
264 SDR_ERRNO_TO_SDR_ERRNUM (ctx, errno);
265 goto cleanup;
266 }
267 }
268 else if (record_type == IPMI_SDR_FORMAT_COMPACT_SENSOR_RECORD)
269 {
270 if (!(obj_sdr_record = fiid_obj_create (tmpl_sdr_compact_sensor_record)))
271 {
272 SDR_ERRNO_TO_SDR_ERRNUM (ctx, errno);
273 goto cleanup;
274 }
275 }
276 else if (record_type == IPMI_SDR_FORMAT_EVENT_ONLY_RECORD)
277 {
278 if (!(obj_sdr_record = fiid_obj_create (tmpl_sdr_event_only_record)))
279 {
280 SDR_ERRNO_TO_SDR_ERRNUM (ctx, errno);
281 goto cleanup;
282 }
283 }
284 else if (record_type == IPMI_SDR_FORMAT_ENTITY_ASSOCIATION_RECORD)
285 {
286 if (!(obj_sdr_record = fiid_obj_create (tmpl_sdr_entity_association_record)))
287 {
288 SDR_ERRNO_TO_SDR_ERRNUM (ctx, errno);
289 goto cleanup;
290 }
291 }
292 else if (record_type == IPMI_SDR_FORMAT_DEVICE_RELATIVE_ENTITY_ASSOCIATION_RECORD)
293 {
294 if (!(obj_sdr_record = fiid_obj_create (tmpl_sdr_device_relative_entity_association_record)))
295 {
296 SDR_ERRNO_TO_SDR_ERRNUM (ctx, errno);
297 goto cleanup;
298 }
299 }
300 else if (record_type == IPMI_SDR_FORMAT_GENERIC_DEVICE_LOCATOR_RECORD)
301 {
302 if (!(obj_sdr_record = fiid_obj_create (tmpl_sdr_generic_device_locator_record)))
303 {
304 SDR_ERRNO_TO_SDR_ERRNUM (ctx, errno);
305 goto cleanup;
306 }
307 }
308 else if (record_type == IPMI_SDR_FORMAT_FRU_DEVICE_LOCATOR_RECORD)
309 {
310 if (!(obj_sdr_record = fiid_obj_create (tmpl_sdr_fru_device_locator_record)))
311 {
312 SDR_ERRNO_TO_SDR_ERRNUM (ctx, errno);
313 goto cleanup;
314 }
315 }
316 else if (record_type == IPMI_SDR_FORMAT_MANAGEMENT_CONTROLLER_DEVICE_LOCATOR_RECORD)
317 {
318 if (!(obj_sdr_record = fiid_obj_create (tmpl_sdr_management_controller_device_locator_record)))
319 {
320 SDR_ERRNO_TO_SDR_ERRNUM (ctx, errno);
321 goto cleanup;
322 }
323 }
324 else if (record_type == IPMI_SDR_FORMAT_MANAGEMENT_CONTROLLER_CONFIRMATION_RECORD)
325 {
326 if (!(obj_sdr_record = fiid_obj_create (tmpl_sdr_management_controller_confirmation_record)))
327 {
328 SDR_ERRNO_TO_SDR_ERRNUM (ctx, errno);
329 goto cleanup;
330 }
331 }
332 else if (record_type == IPMI_SDR_FORMAT_BMC_MESSAGE_CHANNEL_INFO_RECORD)
333 {
334 if (!(obj_sdr_record = fiid_obj_create (tmpl_sdr_bmc_message_channel_info_record)))
335 {
336 SDR_ERRNO_TO_SDR_ERRNUM (ctx, errno);
337 goto cleanup;
338 }
339 }
340 else if (record_type == IPMI_SDR_FORMAT_OEM_RECORD)
341 {
342 if (!(obj_sdr_record = fiid_obj_create (tmpl_sdr_oem_record)))
343 {
344 SDR_ERRNO_TO_SDR_ERRNUM (ctx, errno);
345 goto cleanup;
346 }
347 }
348
349 if (fiid_obj_set_all (obj_sdr_record,
350 sdr_record_to_use,
351 sdr_record_len_to_use) < 0)
352 {
353 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
354 goto cleanup;
355 }
356
357 sdr_check_read_status (ctx);
358
359 return (obj_sdr_record);
360
361 cleanup:
362 fiid_obj_destroy (obj_sdr_record);
363 return (NULL);
364 }
365
366 int
ipmi_sdr_parse_sensor_owner_id(ipmi_sdr_ctx_t ctx,const void * sdr_record,unsigned int sdr_record_len,uint8_t * sensor_owner_id_type,uint8_t * sensor_owner_id)367 ipmi_sdr_parse_sensor_owner_id (ipmi_sdr_ctx_t ctx,
368 const void *sdr_record,
369 unsigned int sdr_record_len,
370 uint8_t *sensor_owner_id_type,
371 uint8_t *sensor_owner_id)
372 {
373 fiid_obj_t obj_sdr_record = NULL;
374 uint32_t acceptable_record_types;
375 uint64_t val;
376 int rv = -1;
377
378 acceptable_record_types = IPMI_SDR_PARSE_RECORD_TYPE_FULL_SENSOR_RECORD;
379 acceptable_record_types |= IPMI_SDR_PARSE_RECORD_TYPE_COMPACT_SENSOR_RECORD;
380 acceptable_record_types |= IPMI_SDR_PARSE_RECORD_TYPE_EVENT_ONLY_RECORD;
381
382 if (!(obj_sdr_record = _sdr_record_get_common (ctx,
383 sdr_record,
384 sdr_record_len,
385 acceptable_record_types)))
386 goto cleanup;
387
388 if (sensor_owner_id_type)
389 {
390 if (FIID_OBJ_GET (obj_sdr_record,
391 "sensor_owner_id.type",
392 &val) < 0)
393 {
394 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
395 goto cleanup;
396 }
397 *sensor_owner_id_type = val;
398 }
399
400 if (sensor_owner_id)
401 {
402 if (FIID_OBJ_GET (obj_sdr_record,
403 "sensor_owner_id",
404 &val) < 0)
405 {
406 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
407 goto cleanup;
408 }
409 *sensor_owner_id = val;
410 }
411
412 rv = 0;
413 ctx->errnum = IPMI_SDR_ERR_SUCCESS;
414 cleanup:
415 fiid_obj_destroy (obj_sdr_record);
416 return (rv);
417 }
418
419 int
ipmi_sdr_parse_sensor_owner_lun(ipmi_sdr_ctx_t ctx,const void * sdr_record,unsigned int sdr_record_len,uint8_t * sensor_owner_lun,uint8_t * channel_number)420 ipmi_sdr_parse_sensor_owner_lun (ipmi_sdr_ctx_t ctx,
421 const void *sdr_record,
422 unsigned int sdr_record_len,
423 uint8_t *sensor_owner_lun,
424 uint8_t *channel_number)
425 {
426 fiid_obj_t obj_sdr_record = NULL;
427 uint32_t acceptable_record_types;
428 uint64_t val;
429 int rv = -1;
430
431 acceptable_record_types = IPMI_SDR_PARSE_RECORD_TYPE_FULL_SENSOR_RECORD;
432 acceptable_record_types |= IPMI_SDR_PARSE_RECORD_TYPE_COMPACT_SENSOR_RECORD;
433 acceptable_record_types |= IPMI_SDR_PARSE_RECORD_TYPE_EVENT_ONLY_RECORD;
434
435 if (!(obj_sdr_record = _sdr_record_get_common (ctx,
436 sdr_record,
437 sdr_record_len,
438 acceptable_record_types)))
439 goto cleanup;
440
441 if (sensor_owner_lun)
442 {
443 if (FIID_OBJ_GET (obj_sdr_record,
444 "sensor_owner_lun",
445 &val) < 0)
446 {
447 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
448 goto cleanup;
449 }
450 *sensor_owner_lun = val;
451 }
452
453 if (channel_number)
454 {
455 if (FIID_OBJ_GET (obj_sdr_record,
456 "channel_number",
457 &val) < 0)
458 {
459 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
460 goto cleanup;
461 }
462 *channel_number = val;
463 }
464
465 rv = 0;
466 ctx->errnum = IPMI_SDR_ERR_SUCCESS;
467 cleanup:
468 fiid_obj_destroy (obj_sdr_record);
469 return (rv);
470 }
471
472 int
ipmi_sdr_parse_sensor_number(ipmi_sdr_ctx_t ctx,const void * sdr_record,unsigned int sdr_record_len,uint8_t * sensor_number)473 ipmi_sdr_parse_sensor_number (ipmi_sdr_ctx_t ctx,
474 const void *sdr_record,
475 unsigned int sdr_record_len,
476 uint8_t *sensor_number)
477 {
478 fiid_obj_t obj_sdr_record = NULL;
479 uint32_t acceptable_record_types;
480 uint64_t val;
481 int rv = -1;
482
483 acceptable_record_types = IPMI_SDR_PARSE_RECORD_TYPE_FULL_SENSOR_RECORD;
484 acceptable_record_types |= IPMI_SDR_PARSE_RECORD_TYPE_COMPACT_SENSOR_RECORD;
485 acceptable_record_types |= IPMI_SDR_PARSE_RECORD_TYPE_EVENT_ONLY_RECORD;
486
487 if (!(obj_sdr_record = _sdr_record_get_common (ctx,
488 sdr_record,
489 sdr_record_len,
490 acceptable_record_types)))
491 goto cleanup;
492
493 if (sensor_number)
494 {
495 if (FIID_OBJ_GET (obj_sdr_record,
496 "sensor_number",
497 &val) < 0)
498 {
499 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
500 goto cleanup;
501 }
502 *sensor_number = val;
503 }
504
505 rv = 0;
506 ctx->errnum = IPMI_SDR_ERR_SUCCESS;
507 cleanup:
508 fiid_obj_destroy (obj_sdr_record);
509 return (rv);
510 }
511
512 int
ipmi_sdr_parse_entity_id_instance_type(ipmi_sdr_ctx_t ctx,const void * sdr_record,unsigned int sdr_record_len,uint8_t * entity_id,uint8_t * entity_instance,uint8_t * entity_instance_type)513 ipmi_sdr_parse_entity_id_instance_type (ipmi_sdr_ctx_t ctx,
514 const void *sdr_record,
515 unsigned int sdr_record_len,
516 uint8_t *entity_id,
517 uint8_t *entity_instance,
518 uint8_t *entity_instance_type)
519 {
520 fiid_obj_t obj_sdr_record = NULL;
521 uint32_t acceptable_record_types;
522 uint64_t val;
523 int rv = -1;
524
525 acceptable_record_types = IPMI_SDR_PARSE_RECORD_TYPE_FULL_SENSOR_RECORD;
526 acceptable_record_types |= IPMI_SDR_PARSE_RECORD_TYPE_COMPACT_SENSOR_RECORD;
527 acceptable_record_types |= IPMI_SDR_PARSE_RECORD_TYPE_EVENT_ONLY_RECORD;
528 acceptable_record_types |= IPMI_SDR_PARSE_RECORD_TYPE_GENERIC_DEVICE_LOCATOR_RECORD;
529 acceptable_record_types |= IPMI_SDR_PARSE_RECORD_TYPE_MANAGEMENT_CONTROLLER_DEVICE_LOCATOR_RECORD;
530
531 if (!(obj_sdr_record = _sdr_record_get_common (ctx,
532 sdr_record,
533 sdr_record_len,
534 acceptable_record_types)))
535 goto cleanup;
536
537 if (entity_id)
538 {
539 if (FIID_OBJ_GET (obj_sdr_record,
540 "entity_id",
541 &val) < 0)
542 {
543 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
544 goto cleanup;
545 }
546 *entity_id = val;
547 }
548 if (entity_instance)
549 {
550 if (FIID_OBJ_GET (obj_sdr_record,
551 "entity_instance",
552 &val) < 0)
553 {
554 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
555 goto cleanup;
556 }
557 *entity_instance = val;
558 }
559 if (entity_instance_type)
560 {
561 if (FIID_OBJ_GET (obj_sdr_record,
562 "entity_instance.type",
563 &val) < 0)
564 {
565 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
566 goto cleanup;
567 }
568 *entity_instance_type = val;
569 }
570
571 rv = 0;
572 ctx->errnum = IPMI_SDR_ERR_SUCCESS;
573 cleanup:
574 fiid_obj_destroy (obj_sdr_record);
575 return (rv);
576 }
577
578 int
ipmi_sdr_parse_sensor_type(ipmi_sdr_ctx_t ctx,const void * sdr_record,unsigned int sdr_record_len,uint8_t * sensor_type)579 ipmi_sdr_parse_sensor_type (ipmi_sdr_ctx_t ctx,
580 const void *sdr_record,
581 unsigned int sdr_record_len,
582 uint8_t *sensor_type)
583 {
584 fiid_obj_t obj_sdr_record = NULL;
585 uint32_t acceptable_record_types;
586 uint64_t val;
587 int rv = -1;
588
589 acceptable_record_types = IPMI_SDR_PARSE_RECORD_TYPE_FULL_SENSOR_RECORD;
590 acceptable_record_types |= IPMI_SDR_PARSE_RECORD_TYPE_COMPACT_SENSOR_RECORD;
591 acceptable_record_types |= IPMI_SDR_PARSE_RECORD_TYPE_EVENT_ONLY_RECORD;
592
593 if (!(obj_sdr_record = _sdr_record_get_common (ctx,
594 sdr_record,
595 sdr_record_len,
596 acceptable_record_types)))
597 goto cleanup;
598
599 if (sensor_type)
600 {
601 if (FIID_OBJ_GET (obj_sdr_record,
602 "sensor_type",
603 &val) < 0)
604 {
605 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
606 goto cleanup;
607 }
608 *sensor_type = val;
609 }
610
611 rv = 0;
612 ctx->errnum = IPMI_SDR_ERR_SUCCESS;
613 cleanup:
614 fiid_obj_destroy (obj_sdr_record);
615 return (rv);
616 }
617
618 int
ipmi_sdr_parse_event_reading_type_code(ipmi_sdr_ctx_t ctx,const void * sdr_record,unsigned int sdr_record_len,uint8_t * event_reading_type_code)619 ipmi_sdr_parse_event_reading_type_code (ipmi_sdr_ctx_t ctx,
620 const void *sdr_record,
621 unsigned int sdr_record_len,
622 uint8_t *event_reading_type_code)
623 {
624 fiid_obj_t obj_sdr_record = NULL;
625 uint32_t acceptable_record_types;
626 uint64_t val;
627 int rv = -1;
628
629 acceptable_record_types = IPMI_SDR_PARSE_RECORD_TYPE_FULL_SENSOR_RECORD;
630 acceptable_record_types |= IPMI_SDR_PARSE_RECORD_TYPE_COMPACT_SENSOR_RECORD;
631 acceptable_record_types |= IPMI_SDR_PARSE_RECORD_TYPE_EVENT_ONLY_RECORD;
632
633 if (!(obj_sdr_record = _sdr_record_get_common (ctx,
634 sdr_record,
635 sdr_record_len,
636 acceptable_record_types)))
637 goto cleanup;
638
639 if (event_reading_type_code)
640 {
641 if (FIID_OBJ_GET (obj_sdr_record,
642 "event_reading_type_code",
643 &val) < 0)
644 {
645 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
646 goto cleanup;
647 }
648 *event_reading_type_code = val;
649 }
650
651 rv = 0;
652 ctx->errnum = IPMI_SDR_ERR_SUCCESS;
653 cleanup:
654 fiid_obj_destroy (obj_sdr_record);
655 return (rv);
656 }
657
658 int
ipmi_sdr_parse_id_string(ipmi_sdr_ctx_t ctx,const void * sdr_record,unsigned int sdr_record_len,char * id_string,unsigned int id_string_len)659 ipmi_sdr_parse_id_string (ipmi_sdr_ctx_t ctx,
660 const void *sdr_record,
661 unsigned int sdr_record_len,
662 char *id_string,
663 unsigned int id_string_len)
664 {
665 fiid_obj_t obj_sdr_record = NULL;
666 uint32_t acceptable_record_types;
667 int len = 0;
668 int rv = -1;
669
670 acceptable_record_types = IPMI_SDR_PARSE_RECORD_TYPE_FULL_SENSOR_RECORD;
671 acceptable_record_types |= IPMI_SDR_PARSE_RECORD_TYPE_COMPACT_SENSOR_RECORD;
672 acceptable_record_types |= IPMI_SDR_PARSE_RECORD_TYPE_EVENT_ONLY_RECORD;
673
674 if (!(obj_sdr_record = _sdr_record_get_common (ctx,
675 sdr_record,
676 sdr_record_len,
677 acceptable_record_types)))
678 goto cleanup;
679
680 if (id_string && id_string_len)
681 {
682 if ((len = fiid_obj_get_data (obj_sdr_record,
683 "id_string",
684 id_string,
685 id_string_len)) < 0)
686 {
687 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
688 goto cleanup;
689 }
690 }
691
692 rv = len;
693 ctx->errnum = IPMI_SDR_ERR_SUCCESS;
694 cleanup:
695 fiid_obj_destroy (obj_sdr_record);
696 return (rv);
697 }
698
699 int
ipmi_sdr_parse_sensor_units(ipmi_sdr_ctx_t ctx,const void * sdr_record,unsigned int sdr_record_len,uint8_t * sensor_units_percentage,uint8_t * sensor_units_modifier,uint8_t * sensor_units_rate,uint8_t * sensor_base_unit_type,uint8_t * sensor_modifier_unit_type)700 ipmi_sdr_parse_sensor_units (ipmi_sdr_ctx_t ctx,
701 const void *sdr_record,
702 unsigned int sdr_record_len,
703 uint8_t *sensor_units_percentage,
704 uint8_t *sensor_units_modifier,
705 uint8_t *sensor_units_rate,
706 uint8_t *sensor_base_unit_type,
707 uint8_t *sensor_modifier_unit_type)
708 {
709 fiid_obj_t obj_sdr_record = NULL;
710 uint32_t acceptable_record_types;
711 uint64_t val;
712 int rv = -1;
713
714 acceptable_record_types = IPMI_SDR_PARSE_RECORD_TYPE_FULL_SENSOR_RECORD;
715 acceptable_record_types |= IPMI_SDR_PARSE_RECORD_TYPE_COMPACT_SENSOR_RECORD;
716
717 if (!(obj_sdr_record = _sdr_record_get_common (ctx,
718 sdr_record,
719 sdr_record_len,
720 acceptable_record_types)))
721 goto cleanup;
722
723 if (sensor_units_percentage)
724 {
725 if (FIID_OBJ_GET (obj_sdr_record,
726 "sensor_unit1.percentage",
727 &val) < 0)
728 {
729 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
730 goto cleanup;
731 }
732 *sensor_units_percentage = val;
733 }
734
735 if (sensor_units_modifier)
736 {
737 if (FIID_OBJ_GET (obj_sdr_record,
738 "sensor_unit1.modifier_unit",
739 &val) < 0)
740 {
741 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
742 goto cleanup;
743 }
744 *sensor_units_modifier = val;
745 }
746
747 if (sensor_units_rate)
748 {
749 if (FIID_OBJ_GET (obj_sdr_record,
750 "sensor_unit1.rate_unit",
751 &val) < 0)
752 {
753 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
754 goto cleanup;
755 }
756
757 *sensor_units_rate = val;
758 }
759
760 if (sensor_base_unit_type)
761 {
762 if (FIID_OBJ_GET (obj_sdr_record,
763 "sensor_unit2.base_unit",
764 &val) < 0)
765 {
766 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
767 goto cleanup;
768 }
769 *sensor_base_unit_type = val;
770
771 if (!IPMI_SENSOR_UNIT_VALID (*sensor_base_unit_type))
772 *sensor_base_unit_type = IPMI_SENSOR_UNIT_UNSPECIFIED;
773 }
774
775 if (sensor_modifier_unit_type)
776 {
777 if (FIID_OBJ_GET (obj_sdr_record,
778 "sensor_unit3.modifier_unit",
779 &val) < 0)
780 {
781 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
782 goto cleanup;
783 }
784 *sensor_modifier_unit_type = val;
785
786 if (!IPMI_SENSOR_UNIT_VALID (*sensor_modifier_unit_type))
787 *sensor_modifier_unit_type = IPMI_SENSOR_UNIT_UNSPECIFIED;
788 }
789
790 rv = 0;
791 ctx->errnum = IPMI_SDR_ERR_SUCCESS;
792 cleanup:
793 fiid_obj_destroy (obj_sdr_record);
794 return (rv);
795 }
796
797 int
ipmi_sdr_parse_sensor_capabilities(ipmi_sdr_ctx_t ctx,const void * sdr_record,unsigned int sdr_record_len,uint8_t * event_message_control_support,uint8_t * threshold_access_support,uint8_t * hysteresis_support,uint8_t * auto_re_arm_support,uint8_t * entity_ignore_support)798 ipmi_sdr_parse_sensor_capabilities (ipmi_sdr_ctx_t ctx,
799 const void *sdr_record,
800 unsigned int sdr_record_len,
801 uint8_t *event_message_control_support,
802 uint8_t *threshold_access_support,
803 uint8_t *hysteresis_support,
804 uint8_t *auto_re_arm_support,
805 uint8_t *entity_ignore_support)
806 {
807 fiid_obj_t obj_sdr_record = NULL;
808 uint32_t acceptable_record_types;
809 uint64_t val;
810 int rv = -1;
811
812 acceptable_record_types = IPMI_SDR_PARSE_RECORD_TYPE_FULL_SENSOR_RECORD;
813 acceptable_record_types |= IPMI_SDR_PARSE_RECORD_TYPE_COMPACT_SENSOR_RECORD;
814
815 if (!(obj_sdr_record = _sdr_record_get_common (ctx,
816 sdr_record,
817 sdr_record_len,
818 acceptable_record_types)))
819 goto cleanup;
820
821 if (event_message_control_support)
822 {
823 if (FIID_OBJ_GET (obj_sdr_record,
824 "sensor_capabilities.event_message_control_support",
825 &val) < 0)
826 {
827 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
828 goto cleanup;
829 }
830 *event_message_control_support = val;
831 }
832 if (threshold_access_support)
833 {
834 if (FIID_OBJ_GET (obj_sdr_record,
835 "sensor_capabilities.threshold_access_support",
836 &val) < 0)
837 {
838 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
839 goto cleanup;
840 }
841 *threshold_access_support = val;
842 }
843 if (hysteresis_support)
844 {
845 if (FIID_OBJ_GET (obj_sdr_record,
846 "sensor_capabilities.hysteresis_support",
847 &val) < 0)
848 {
849 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
850 goto cleanup;
851 }
852 *hysteresis_support = val;
853 }
854 if (auto_re_arm_support)
855 {
856 if (FIID_OBJ_GET (obj_sdr_record,
857 "sensor_capabilities.auto_re_arm_support",
858 &val) < 0)
859 {
860 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
861 goto cleanup;
862 }
863 *auto_re_arm_support = val;
864 }
865 if (entity_ignore_support)
866 {
867 if (FIID_OBJ_GET (obj_sdr_record,
868 "sensor_capabilities.entity_ignore_support",
869 &val) < 0)
870 {
871 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
872 goto cleanup;
873 }
874 *entity_ignore_support = val;
875 }
876
877 rv = 0;
878 ctx->errnum = IPMI_SDR_ERR_SUCCESS;
879 cleanup:
880 fiid_obj_destroy (obj_sdr_record);
881 return (rv);
882 }
883
884 int
ipmi_sdr_parse_sensor_direction(ipmi_sdr_ctx_t ctx,const void * sdr_record,unsigned int sdr_record_len,uint8_t * sensor_direction)885 ipmi_sdr_parse_sensor_direction (ipmi_sdr_ctx_t ctx,
886 const void *sdr_record,
887 unsigned int sdr_record_len,
888 uint8_t *sensor_direction)
889 {
890 fiid_obj_t obj_sdr_record = NULL;
891 uint32_t acceptable_record_types;
892 uint64_t val;
893 int rv = -1;
894
895 acceptable_record_types = IPMI_SDR_PARSE_RECORD_TYPE_FULL_SENSOR_RECORD;
896 acceptable_record_types |= IPMI_SDR_PARSE_RECORD_TYPE_COMPACT_SENSOR_RECORD;
897
898 if (!(obj_sdr_record = _sdr_record_get_common (ctx,
899 sdr_record,
900 sdr_record_len,
901 acceptable_record_types)))
902 goto cleanup;
903
904 if (sensor_direction)
905 {
906 if (FIID_OBJ_GET (obj_sdr_record,
907 "sensor_direction",
908 &val) < 0)
909 {
910 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
911 goto cleanup;
912 }
913 *sensor_direction = val;
914 }
915
916 rv = 0;
917 ctx->errnum = IPMI_SDR_ERR_SUCCESS;
918 cleanup:
919 fiid_obj_destroy (obj_sdr_record);
920 return (rv);
921 }
922
923 int
ipmi_sdr_parse_assertion_supported(ipmi_sdr_ctx_t ctx,const void * sdr_record,unsigned int sdr_record_len,uint8_t * event_state_0,uint8_t * event_state_1,uint8_t * event_state_2,uint8_t * event_state_3,uint8_t * event_state_4,uint8_t * event_state_5,uint8_t * event_state_6,uint8_t * event_state_7,uint8_t * event_state_8,uint8_t * event_state_9,uint8_t * event_state_10,uint8_t * event_state_11,uint8_t * event_state_12,uint8_t * event_state_13,uint8_t * event_state_14)924 ipmi_sdr_parse_assertion_supported (ipmi_sdr_ctx_t ctx,
925 const void *sdr_record,
926 unsigned int sdr_record_len,
927 uint8_t *event_state_0,
928 uint8_t *event_state_1,
929 uint8_t *event_state_2,
930 uint8_t *event_state_3,
931 uint8_t *event_state_4,
932 uint8_t *event_state_5,
933 uint8_t *event_state_6,
934 uint8_t *event_state_7,
935 uint8_t *event_state_8,
936 uint8_t *event_state_9,
937 uint8_t *event_state_10,
938 uint8_t *event_state_11,
939 uint8_t *event_state_12,
940 uint8_t *event_state_13,
941 uint8_t *event_state_14)
942 {
943 fiid_obj_t obj_sdr_record = NULL;
944 fiid_obj_t obj_sdr_record_discrete = NULL;
945 uint32_t acceptable_record_types;
946 uint8_t record_type;
947 uint8_t event_reading_type_code;
948 uint64_t val;
949 int rv = -1;
950
951 acceptable_record_types = IPMI_SDR_PARSE_RECORD_TYPE_FULL_SENSOR_RECORD;
952 acceptable_record_types |= IPMI_SDR_PARSE_RECORD_TYPE_COMPACT_SENSOR_RECORD;
953
954 if (!(obj_sdr_record = _sdr_record_get_common (ctx,
955 sdr_record,
956 sdr_record_len,
957 acceptable_record_types)))
958 goto cleanup;
959
960 if (ipmi_sdr_parse_event_reading_type_code (ctx,
961 sdr_record,
962 sdr_record_len,
963 &event_reading_type_code) < 0)
964 goto cleanup;
965
966 if (!IPMI_EVENT_READING_TYPE_CODE_IS_GENERIC (event_reading_type_code)
967 && !IPMI_EVENT_READING_TYPE_CODE_IS_SENSOR_SPECIFIC (event_reading_type_code))
968 {
969 SDR_SET_ERRNUM (ctx, IPMI_SDR_ERR_PARSE_INVALID_SDR_RECORD);
970 goto cleanup;
971 }
972
973 /* convert obj_sdr_record to appropriate format we care about */
974 if (ipmi_sdr_parse_record_id_and_type (ctx,
975 sdr_record,
976 sdr_record_len,
977 NULL,
978 &record_type) < 0)
979 goto cleanup;
980
981 if (record_type == IPMI_SDR_FORMAT_FULL_SENSOR_RECORD)
982 {
983 if (!(obj_sdr_record_discrete = fiid_obj_copy (obj_sdr_record,
984 tmpl_sdr_full_sensor_record_non_threshold_based_sensors)))
985 {
986 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
987 goto cleanup;
988 }
989 }
990 else
991 {
992 if (!(obj_sdr_record_discrete = fiid_obj_copy (obj_sdr_record,
993 tmpl_sdr_compact_sensor_record_non_threshold_based_sensors)))
994 {
995 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
996 goto cleanup;
997 }
998 }
999
1000 if (event_state_0)
1001 {
1002 if (FIID_OBJ_GET (obj_sdr_record_discrete,
1003 "assertion_event_mask.event_offset_0",
1004 &val) < 0)
1005 {
1006 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record_discrete);
1007 goto cleanup;
1008 }
1009 *event_state_0 = val;
1010 }
1011
1012 if (event_state_1)
1013 {
1014 if (FIID_OBJ_GET (obj_sdr_record_discrete,
1015 "assertion_event_mask.event_offset_1",
1016 &val) < 0)
1017 {
1018 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record_discrete);
1019 goto cleanup;
1020 }
1021 *event_state_1 = val;
1022 }
1023
1024 if (event_state_2)
1025 {
1026 if (FIID_OBJ_GET (obj_sdr_record_discrete,
1027 "assertion_event_mask.event_offset_2",
1028 &val) < 0)
1029 {
1030 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record_discrete);
1031 goto cleanup;
1032 }
1033 *event_state_2 = val;
1034 }
1035
1036 if (event_state_3)
1037 {
1038 if (FIID_OBJ_GET (obj_sdr_record_discrete,
1039 "assertion_event_mask.event_offset_3",
1040 &val) < 0)
1041 {
1042 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record_discrete);
1043 goto cleanup;
1044 }
1045 *event_state_3 = val;
1046 }
1047
1048 if (event_state_4)
1049 {
1050 if (FIID_OBJ_GET (obj_sdr_record_discrete,
1051 "assertion_event_mask.event_offset_4",
1052 &val) < 0)
1053 {
1054 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record_discrete);
1055 goto cleanup;
1056 }
1057 *event_state_4 = val;
1058 }
1059
1060 if (event_state_5)
1061 {
1062 if (FIID_OBJ_GET (obj_sdr_record_discrete,
1063 "assertion_event_mask.event_offset_5",
1064 &val) < 0)
1065 {
1066 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record_discrete);
1067 goto cleanup;
1068 }
1069 *event_state_5 = val;
1070 }
1071
1072 if (event_state_6)
1073 {
1074 if (FIID_OBJ_GET (obj_sdr_record_discrete,
1075 "assertion_event_mask.event_offset_6",
1076 &val) < 0)
1077 {
1078 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record_discrete);
1079 goto cleanup;
1080 }
1081 *event_state_6 = val;
1082 }
1083
1084 if (event_state_7)
1085 {
1086 if (FIID_OBJ_GET (obj_sdr_record_discrete,
1087 "assertion_event_mask.event_offset_7",
1088 &val) < 0)
1089 {
1090 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record_discrete);
1091 goto cleanup;
1092 }
1093 *event_state_7 = val;
1094 }
1095
1096 if (event_state_8)
1097 {
1098 if (FIID_OBJ_GET (obj_sdr_record_discrete,
1099 "assertion_event_mask.event_offset_8",
1100 &val) < 0)
1101 {
1102 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record_discrete);
1103 goto cleanup;
1104 }
1105 *event_state_8 = val;
1106 }
1107
1108 if (event_state_9)
1109 {
1110 if (FIID_OBJ_GET (obj_sdr_record_discrete,
1111 "assertion_event_mask.event_offset_9",
1112 &val) < 0)
1113 {
1114 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record_discrete);
1115 goto cleanup;
1116 }
1117 *event_state_9 = val;
1118 }
1119
1120 if (event_state_10)
1121 {
1122 if (FIID_OBJ_GET (obj_sdr_record_discrete,
1123 "assertion_event_mask.event_offset_10",
1124 &val) < 0)
1125 {
1126 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record_discrete);
1127 goto cleanup;
1128 }
1129 *event_state_10 = val;
1130 }
1131
1132 if (event_state_11)
1133 {
1134 if (FIID_OBJ_GET (obj_sdr_record_discrete,
1135 "assertion_event_mask.event_offset_11",
1136 &val) < 0)
1137 {
1138 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record_discrete);
1139 goto cleanup;
1140 }
1141 *event_state_11 = val;
1142 }
1143
1144 if (event_state_12)
1145 {
1146 if (FIID_OBJ_GET (obj_sdr_record_discrete,
1147 "assertion_event_mask.event_offset_12",
1148 &val) < 0)
1149 {
1150 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record_discrete);
1151 goto cleanup;
1152 }
1153 *event_state_12 = val;
1154 }
1155
1156 if (event_state_13)
1157 {
1158 if (FIID_OBJ_GET (obj_sdr_record_discrete,
1159 "assertion_event_mask.event_offset_13",
1160 &val) < 0)
1161 {
1162 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record_discrete);
1163 goto cleanup;
1164 }
1165 *event_state_13 = val;
1166 }
1167
1168 if (event_state_14)
1169 {
1170 if (FIID_OBJ_GET (obj_sdr_record_discrete,
1171 "assertion_event_mask.event_offset_14",
1172 &val) < 0)
1173 {
1174 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record_discrete);
1175 goto cleanup;
1176 }
1177 *event_state_14 = val;
1178 }
1179
1180 rv = 0;
1181 ctx->errnum = IPMI_SDR_ERR_SUCCESS;
1182 cleanup:
1183 fiid_obj_destroy (obj_sdr_record);
1184 fiid_obj_destroy (obj_sdr_record_discrete);
1185 return (rv);
1186 }
1187
1188 int
ipmi_sdr_parse_deassertion_supported(ipmi_sdr_ctx_t ctx,const void * sdr_record,unsigned int sdr_record_len,uint8_t * event_state_0,uint8_t * event_state_1,uint8_t * event_state_2,uint8_t * event_state_3,uint8_t * event_state_4,uint8_t * event_state_5,uint8_t * event_state_6,uint8_t * event_state_7,uint8_t * event_state_8,uint8_t * event_state_9,uint8_t * event_state_10,uint8_t * event_state_11,uint8_t * event_state_12,uint8_t * event_state_13,uint8_t * event_state_14)1189 ipmi_sdr_parse_deassertion_supported (ipmi_sdr_ctx_t ctx,
1190 const void *sdr_record,
1191 unsigned int sdr_record_len,
1192 uint8_t *event_state_0,
1193 uint8_t *event_state_1,
1194 uint8_t *event_state_2,
1195 uint8_t *event_state_3,
1196 uint8_t *event_state_4,
1197 uint8_t *event_state_5,
1198 uint8_t *event_state_6,
1199 uint8_t *event_state_7,
1200 uint8_t *event_state_8,
1201 uint8_t *event_state_9,
1202 uint8_t *event_state_10,
1203 uint8_t *event_state_11,
1204 uint8_t *event_state_12,
1205 uint8_t *event_state_13,
1206 uint8_t *event_state_14)
1207 {
1208 fiid_obj_t obj_sdr_record = NULL;
1209 fiid_obj_t obj_sdr_record_discrete = NULL;
1210 uint32_t acceptable_record_types;
1211 uint8_t record_type;
1212 uint8_t event_reading_type_code;
1213 uint64_t val;
1214 int rv = -1;
1215
1216 acceptable_record_types = IPMI_SDR_PARSE_RECORD_TYPE_FULL_SENSOR_RECORD;
1217 acceptable_record_types |= IPMI_SDR_PARSE_RECORD_TYPE_COMPACT_SENSOR_RECORD;
1218
1219 if (!(obj_sdr_record = _sdr_record_get_common (ctx,
1220 sdr_record,
1221 sdr_record_len,
1222 acceptable_record_types)))
1223 goto cleanup;
1224
1225 if (ipmi_sdr_parse_event_reading_type_code (ctx,
1226 sdr_record,
1227 sdr_record_len,
1228 &event_reading_type_code) < 0)
1229 goto cleanup;
1230
1231 if (!IPMI_EVENT_READING_TYPE_CODE_IS_GENERIC (event_reading_type_code)
1232 && !IPMI_EVENT_READING_TYPE_CODE_IS_SENSOR_SPECIFIC (event_reading_type_code))
1233 {
1234 SDR_SET_ERRNUM (ctx, IPMI_SDR_ERR_PARSE_INVALID_SDR_RECORD);
1235 goto cleanup;
1236 }
1237
1238 /* convert obj_sdr_record to appropriate format we care about */
1239 if (ipmi_sdr_parse_record_id_and_type (ctx,
1240 sdr_record,
1241 sdr_record_len,
1242 NULL,
1243 &record_type) < 0)
1244 goto cleanup;
1245
1246 if (record_type == IPMI_SDR_FORMAT_FULL_SENSOR_RECORD)
1247 {
1248 if (!(obj_sdr_record_discrete = fiid_obj_copy (obj_sdr_record,
1249 tmpl_sdr_full_sensor_record_non_threshold_based_sensors)))
1250 {
1251 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
1252 goto cleanup;
1253 }
1254 }
1255 else
1256 {
1257 if (!(obj_sdr_record_discrete = fiid_obj_copy (obj_sdr_record,
1258 tmpl_sdr_compact_sensor_record_non_threshold_based_sensors)))
1259 {
1260 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
1261 goto cleanup;
1262 }
1263 }
1264
1265 if (event_state_0)
1266 {
1267 if (FIID_OBJ_GET (obj_sdr_record_discrete,
1268 "deassertion_event_mask.event_offset_0",
1269 &val) < 0)
1270 {
1271 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record_discrete);
1272 goto cleanup;
1273 }
1274 *event_state_0 = val;
1275 }
1276
1277 if (event_state_1)
1278 {
1279 if (FIID_OBJ_GET (obj_sdr_record_discrete,
1280 "deassertion_event_mask.event_offset_1",
1281 &val) < 0)
1282 {
1283 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record_discrete);
1284 goto cleanup;
1285 }
1286 *event_state_1 = val;
1287 }
1288
1289 if (event_state_2)
1290 {
1291 if (FIID_OBJ_GET (obj_sdr_record_discrete,
1292 "deassertion_event_mask.event_offset_2",
1293 &val) < 0)
1294 {
1295 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record_discrete);
1296 goto cleanup;
1297 }
1298 *event_state_2 = val;
1299 }
1300
1301 if (event_state_3)
1302 {
1303 if (FIID_OBJ_GET (obj_sdr_record_discrete,
1304 "deassertion_event_mask.event_offset_3",
1305 &val) < 0)
1306 {
1307 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record_discrete);
1308 goto cleanup;
1309 }
1310 *event_state_3 = val;
1311 }
1312
1313 if (event_state_4)
1314 {
1315 if (FIID_OBJ_GET (obj_sdr_record_discrete,
1316 "deassertion_event_mask.event_offset_4",
1317 &val) < 0)
1318 {
1319 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record_discrete);
1320 goto cleanup;
1321 }
1322 *event_state_4 = val;
1323 }
1324
1325 if (event_state_5)
1326 {
1327 if (FIID_OBJ_GET (obj_sdr_record_discrete,
1328 "deassertion_event_mask.event_offset_5",
1329 &val) < 0)
1330 {
1331 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record_discrete);
1332 goto cleanup;
1333 }
1334 *event_state_5 = val;
1335 }
1336
1337 if (event_state_6)
1338 {
1339 if (FIID_OBJ_GET (obj_sdr_record_discrete,
1340 "deassertion_event_mask.event_offset_6",
1341 &val) < 0)
1342 {
1343 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record_discrete);
1344 goto cleanup;
1345 }
1346 *event_state_6 = val;
1347 }
1348
1349 if (event_state_7)
1350 {
1351 if (FIID_OBJ_GET (obj_sdr_record_discrete,
1352 "deassertion_event_mask.event_offset_7",
1353 &val) < 0)
1354 {
1355 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record_discrete);
1356 goto cleanup;
1357 }
1358 *event_state_7 = val;
1359 }
1360
1361 if (event_state_8)
1362 {
1363 if (FIID_OBJ_GET (obj_sdr_record_discrete,
1364 "deassertion_event_mask.event_offset_8",
1365 &val) < 0)
1366 {
1367 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record_discrete);
1368 goto cleanup;
1369 }
1370 *event_state_8 = val;
1371 }
1372
1373 if (event_state_9)
1374 {
1375 if (FIID_OBJ_GET (obj_sdr_record_discrete,
1376 "deassertion_event_mask.event_offset_9",
1377 &val) < 0)
1378 {
1379 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record_discrete);
1380 goto cleanup;
1381 }
1382 *event_state_9 = val;
1383 }
1384
1385 if (event_state_10)
1386 {
1387 if (FIID_OBJ_GET (obj_sdr_record_discrete,
1388 "deassertion_event_mask.event_offset_10",
1389 &val) < 0)
1390 {
1391 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record_discrete);
1392 goto cleanup;
1393 }
1394 *event_state_10 = val;
1395 }
1396
1397 if (event_state_11)
1398 {
1399 if (FIID_OBJ_GET (obj_sdr_record_discrete,
1400 "deassertion_event_mask.event_offset_11",
1401 &val) < 0)
1402 {
1403 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record_discrete);
1404 goto cleanup;
1405 }
1406 *event_state_11 = val;
1407 }
1408
1409 if (event_state_12)
1410 {
1411 if (FIID_OBJ_GET (obj_sdr_record_discrete,
1412 "deassertion_event_mask.event_offset_12",
1413 &val) < 0)
1414 {
1415 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record_discrete);
1416 goto cleanup;
1417 }
1418 *event_state_12 = val;
1419 }
1420
1421 if (event_state_13)
1422 {
1423 if (FIID_OBJ_GET (obj_sdr_record_discrete,
1424 "deassertion_event_mask.event_offset_13",
1425 &val) < 0)
1426 {
1427 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record_discrete);
1428 goto cleanup;
1429 }
1430 *event_state_13 = val;
1431 }
1432
1433 if (event_state_14)
1434 {
1435 if (FIID_OBJ_GET (obj_sdr_record_discrete,
1436 "deassertion_event_mask.event_offset_14",
1437 &val) < 0)
1438 {
1439 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record_discrete);
1440 goto cleanup;
1441 }
1442 *event_state_14 = val;
1443 }
1444
1445 rv = 0;
1446 ctx->errnum = IPMI_SDR_ERR_SUCCESS;
1447 cleanup:
1448 fiid_obj_destroy (obj_sdr_record);
1449 fiid_obj_destroy (obj_sdr_record_discrete);
1450 return (rv);
1451 }
1452
1453 int
ipmi_sdr_parse_threshold_assertion_supported(ipmi_sdr_ctx_t ctx,const void * sdr_record,unsigned int sdr_record_len,uint8_t * lower_non_critical_going_low,uint8_t * lower_non_critical_going_high,uint8_t * lower_critical_going_low,uint8_t * lower_critical_going_high,uint8_t * lower_non_recoverable_going_low,uint8_t * lower_non_recoverable_going_high,uint8_t * upper_non_critical_going_low,uint8_t * upper_non_critical_going_high,uint8_t * upper_critical_going_low,uint8_t * upper_critical_going_high,uint8_t * upper_non_recoverable_going_low,uint8_t * upper_non_recoverable_going_high)1454 ipmi_sdr_parse_threshold_assertion_supported (ipmi_sdr_ctx_t ctx,
1455 const void *sdr_record,
1456 unsigned int sdr_record_len,
1457 uint8_t *lower_non_critical_going_low,
1458 uint8_t *lower_non_critical_going_high,
1459 uint8_t *lower_critical_going_low,
1460 uint8_t *lower_critical_going_high,
1461 uint8_t *lower_non_recoverable_going_low,
1462 uint8_t *lower_non_recoverable_going_high,
1463 uint8_t *upper_non_critical_going_low,
1464 uint8_t *upper_non_critical_going_high,
1465 uint8_t *upper_critical_going_low,
1466 uint8_t *upper_critical_going_high,
1467 uint8_t *upper_non_recoverable_going_low,
1468 uint8_t *upper_non_recoverable_going_high)
1469 {
1470 fiid_obj_t obj_sdr_record = NULL;
1471 fiid_obj_t obj_sdr_record_threshold = NULL;
1472 uint32_t acceptable_record_types;
1473 uint8_t event_reading_type_code;
1474 uint64_t val;
1475 int rv = -1;
1476
1477 /* achu:
1478 *
1479 * Technically, the IPMI spec lists that compact record formats also
1480 * support settable thresholds. However, since compact records
1481 * don't contain any information for interpreting threshold sensors
1482 * (e.g. R exponent) I don't know how they could be of any use. No
1483 * vendor that I know of supports threshold sensors via a compact
1484 * record (excluding possible OEM ones).
1485 *
1486 * There's a part of me that believes the readable/setting
1487 * threshold masks for compact sensor records is a cut and paste
1488 * typo. It shouldn't be there.
1489 */
1490
1491 acceptable_record_types = IPMI_SDR_PARSE_RECORD_TYPE_FULL_SENSOR_RECORD;
1492
1493 if (!(obj_sdr_record = _sdr_record_get_common (ctx,
1494 sdr_record,
1495 sdr_record_len,
1496 acceptable_record_types)))
1497 goto cleanup;
1498
1499 /* We don't want the generic sdr full record, we need the special
1500 * threshold one.
1501 */
1502
1503 if (ipmi_sdr_parse_event_reading_type_code (ctx,
1504 sdr_record,
1505 sdr_record_len,
1506 &event_reading_type_code) < 0)
1507 goto cleanup;
1508
1509 if (!IPMI_EVENT_READING_TYPE_CODE_IS_THRESHOLD (event_reading_type_code))
1510 {
1511 SDR_SET_ERRNUM (ctx, IPMI_SDR_ERR_PARSE_INVALID_SDR_RECORD);
1512 goto cleanup;
1513 }
1514
1515 if (!(obj_sdr_record_threshold = fiid_obj_copy (obj_sdr_record,
1516 tmpl_sdr_full_sensor_record_threshold_based_sensors)))
1517 {
1518 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
1519 goto cleanup;
1520 }
1521
1522 if (lower_non_critical_going_low)
1523 {
1524 if (FIID_OBJ_GET (obj_sdr_record_threshold,
1525 "threshold_assertion_event_mask.lower_non_critical_going_low_supported",
1526 &val) < 0)
1527 {
1528 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record_threshold);
1529 goto cleanup;
1530 }
1531 *lower_non_critical_going_low = val;
1532 }
1533
1534 if (lower_non_critical_going_high)
1535 {
1536 if (FIID_OBJ_GET (obj_sdr_record_threshold,
1537 "threshold_assertion_event_mask.lower_non_critical_going_high_supported",
1538 &val) < 0)
1539 {
1540 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record_threshold);
1541 goto cleanup;
1542 }
1543 *lower_non_critical_going_high = val;
1544 }
1545
1546 if (lower_critical_going_low)
1547 {
1548 if (FIID_OBJ_GET (obj_sdr_record_threshold,
1549 "threshold_assertion_event_mask.lower_critical_going_low_supported",
1550 &val) < 0)
1551 {
1552 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record_threshold);
1553 goto cleanup;
1554 }
1555 *lower_critical_going_low = val;
1556 }
1557
1558 if (lower_critical_going_high)
1559 {
1560 if (FIID_OBJ_GET (obj_sdr_record_threshold,
1561 "threshold_assertion_event_mask.lower_critical_going_high_supported",
1562 &val) < 0)
1563 {
1564 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record_threshold);
1565 goto cleanup;
1566 }
1567 *lower_critical_going_high = val;
1568 }
1569
1570 if (lower_non_recoverable_going_low)
1571 {
1572 if (FIID_OBJ_GET (obj_sdr_record_threshold,
1573 "threshold_assertion_event_mask.lower_non_recoverable_going_low_supported",
1574 &val) < 0)
1575 {
1576 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record_threshold);
1577 goto cleanup;
1578 }
1579 *lower_non_recoverable_going_low = val;
1580 }
1581
1582 if (lower_non_recoverable_going_high)
1583 {
1584 if (FIID_OBJ_GET (obj_sdr_record_threshold,
1585 "threshold_assertion_event_mask.lower_non_recoverable_going_high_supported",
1586 &val) < 0)
1587 {
1588 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record_threshold);
1589 goto cleanup;
1590 }
1591 *lower_non_recoverable_going_high = val;
1592 }
1593
1594 if (upper_non_critical_going_low)
1595 {
1596 if (FIID_OBJ_GET (obj_sdr_record_threshold,
1597 "threshold_assertion_event_mask.upper_non_critical_going_low_supported",
1598 &val) < 0)
1599 {
1600 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record_threshold);
1601 goto cleanup;
1602 }
1603 *upper_non_critical_going_low = val;
1604 }
1605
1606 if (upper_non_critical_going_high)
1607 {
1608 if (FIID_OBJ_GET (obj_sdr_record_threshold,
1609 "threshold_assertion_event_mask.upper_non_critical_going_high_supported",
1610 &val) < 0)
1611 {
1612 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record_threshold);
1613 goto cleanup;
1614 }
1615 *upper_non_critical_going_high = val;
1616 }
1617
1618 if (upper_critical_going_low)
1619 {
1620 if (FIID_OBJ_GET (obj_sdr_record_threshold,
1621 "threshold_assertion_event_mask.upper_critical_going_low_supported",
1622 &val) < 0)
1623 {
1624 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record_threshold);
1625 goto cleanup;
1626 }
1627 *upper_critical_going_low = val;
1628 }
1629
1630 if (upper_critical_going_high)
1631 {
1632 if (FIID_OBJ_GET (obj_sdr_record_threshold,
1633 "threshold_assertion_event_mask.upper_critical_going_high_supported",
1634 &val) < 0)
1635 {
1636 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record_threshold);
1637 goto cleanup;
1638 }
1639 *upper_critical_going_high = val;
1640 }
1641
1642 if (upper_non_recoverable_going_low)
1643 {
1644 if (FIID_OBJ_GET (obj_sdr_record_threshold,
1645 "threshold_assertion_event_mask.upper_non_recoverable_going_low_supported",
1646 &val) < 0)
1647 {
1648 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record_threshold);
1649 goto cleanup;
1650 }
1651 *upper_non_recoverable_going_low = val;
1652 }
1653
1654 if (upper_non_recoverable_going_high)
1655 {
1656 if (FIID_OBJ_GET (obj_sdr_record_threshold,
1657 "threshold_assertion_event_mask.upper_non_recoverable_going_high_supported",
1658 &val) < 0)
1659 {
1660 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record_threshold);
1661 goto cleanup;
1662 }
1663 *upper_non_recoverable_going_high = val;
1664 }
1665
1666 rv = 0;
1667 ctx->errnum = IPMI_SDR_ERR_SUCCESS;
1668 cleanup:
1669 fiid_obj_destroy (obj_sdr_record);
1670 fiid_obj_destroy (obj_sdr_record_threshold);
1671 return (rv);
1672 }
1673
1674 int
ipmi_sdr_parse_threshold_deassertion_supported(ipmi_sdr_ctx_t ctx,const void * sdr_record,unsigned int sdr_record_len,uint8_t * lower_non_critical_going_low,uint8_t * lower_non_critical_going_high,uint8_t * lower_critical_going_low,uint8_t * lower_critical_going_high,uint8_t * lower_non_recoverable_going_low,uint8_t * lower_non_recoverable_going_high,uint8_t * upper_non_critical_going_low,uint8_t * upper_non_critical_going_high,uint8_t * upper_critical_going_low,uint8_t * upper_critical_going_high,uint8_t * upper_non_recoverable_going_low,uint8_t * upper_non_recoverable_going_high)1675 ipmi_sdr_parse_threshold_deassertion_supported (ipmi_sdr_ctx_t ctx,
1676 const void *sdr_record,
1677 unsigned int sdr_record_len,
1678 uint8_t *lower_non_critical_going_low,
1679 uint8_t *lower_non_critical_going_high,
1680 uint8_t *lower_critical_going_low,
1681 uint8_t *lower_critical_going_high,
1682 uint8_t *lower_non_recoverable_going_low,
1683 uint8_t *lower_non_recoverable_going_high,
1684 uint8_t *upper_non_critical_going_low,
1685 uint8_t *upper_non_critical_going_high,
1686 uint8_t *upper_critical_going_low,
1687 uint8_t *upper_critical_going_high,
1688 uint8_t *upper_non_recoverable_going_low,
1689 uint8_t *upper_non_recoverable_going_high)
1690 {
1691 fiid_obj_t obj_sdr_record = NULL;
1692 fiid_obj_t obj_sdr_record_threshold = NULL;
1693 uint32_t acceptable_record_types;
1694 uint8_t event_reading_type_code;
1695 uint64_t val;
1696 int rv = -1;
1697
1698 /* achu:
1699 *
1700 * Technically, the IPMI spec lists that compact record formats also
1701 * support settable thresholds. However, since compact records
1702 * don't contain any information for interpreting threshold sensors
1703 * (e.g. R exponent) I don't know how they could be of any use. No
1704 * vendor that I know of supports threshold sensors via a compact
1705 * record (excluding possible OEM ones).
1706 *
1707 * There's a part of me that believes the readable/setting
1708 * threshold masks for compact sensor records is a cut and paste
1709 * typo. It shouldn't be there.
1710 */
1711
1712 acceptable_record_types = IPMI_SDR_PARSE_RECORD_TYPE_FULL_SENSOR_RECORD;
1713
1714 if (!(obj_sdr_record = _sdr_record_get_common (ctx,
1715 sdr_record,
1716 sdr_record_len,
1717 acceptable_record_types)))
1718 goto cleanup;
1719
1720 /* We don't want the generic sdr full record, we need the special
1721 * threshold one.
1722 */
1723
1724 if (ipmi_sdr_parse_event_reading_type_code (ctx,
1725 sdr_record,
1726 sdr_record_len,
1727 &event_reading_type_code) < 0)
1728 goto cleanup;
1729
1730 if (!IPMI_EVENT_READING_TYPE_CODE_IS_THRESHOLD (event_reading_type_code))
1731 {
1732 SDR_SET_ERRNUM (ctx, IPMI_SDR_ERR_PARSE_INVALID_SDR_RECORD);
1733 goto cleanup;
1734 }
1735
1736 if (!(obj_sdr_record_threshold = fiid_obj_copy (obj_sdr_record,
1737 tmpl_sdr_full_sensor_record_threshold_based_sensors)))
1738 {
1739 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
1740 goto cleanup;
1741 }
1742
1743 if (lower_non_critical_going_low)
1744 {
1745 if (FIID_OBJ_GET (obj_sdr_record_threshold,
1746 "threshold_deassertion_event_mask.lower_non_critical_going_low_supported",
1747 &val) < 0)
1748 {
1749 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record_threshold);
1750 goto cleanup;
1751 }
1752 *lower_non_critical_going_low = val;
1753 }
1754
1755 if (lower_non_critical_going_high)
1756 {
1757 if (FIID_OBJ_GET (obj_sdr_record_threshold,
1758 "threshold_deassertion_event_mask.lower_non_critical_going_high_supported",
1759 &val) < 0)
1760 {
1761 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record_threshold);
1762 goto cleanup;
1763 }
1764 *lower_non_critical_going_high = val;
1765 }
1766
1767 if (lower_critical_going_low)
1768 {
1769 if (FIID_OBJ_GET (obj_sdr_record_threshold,
1770 "threshold_deassertion_event_mask.lower_critical_going_low_supported",
1771 &val) < 0)
1772 {
1773 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record_threshold);
1774 goto cleanup;
1775 }
1776 *lower_critical_going_low = val;
1777 }
1778
1779 if (lower_critical_going_high)
1780 {
1781 if (FIID_OBJ_GET (obj_sdr_record_threshold,
1782 "threshold_deassertion_event_mask.lower_critical_going_high_supported",
1783 &val) < 0)
1784 {
1785 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record_threshold);
1786 goto cleanup;
1787 }
1788 *lower_critical_going_high = val;
1789 }
1790
1791 if (lower_non_recoverable_going_low)
1792 {
1793 if (FIID_OBJ_GET (obj_sdr_record_threshold,
1794 "threshold_deassertion_event_mask.lower_non_recoverable_going_low_supported",
1795 &val) < 0)
1796 {
1797 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record_threshold);
1798 goto cleanup;
1799 }
1800 *lower_non_recoverable_going_low = val;
1801 }
1802
1803 if (lower_non_recoverable_going_high)
1804 {
1805 if (FIID_OBJ_GET (obj_sdr_record_threshold,
1806 "threshold_deassertion_event_mask.lower_non_recoverable_going_high_supported",
1807 &val) < 0)
1808 {
1809 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record_threshold);
1810 goto cleanup;
1811 }
1812 *lower_non_recoverable_going_high = val;
1813 }
1814
1815 if (upper_non_critical_going_low)
1816 {
1817 if (FIID_OBJ_GET (obj_sdr_record_threshold,
1818 "threshold_deassertion_event_mask.upper_non_critical_going_low_supported",
1819 &val) < 0)
1820 {
1821 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record_threshold);
1822 goto cleanup;
1823 }
1824 *upper_non_critical_going_low = val;
1825 }
1826
1827 if (upper_non_critical_going_high)
1828 {
1829 if (FIID_OBJ_GET (obj_sdr_record_threshold,
1830 "threshold_deassertion_event_mask.upper_non_critical_going_high_supported",
1831 &val) < 0)
1832 {
1833 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record_threshold);
1834 goto cleanup;
1835 }
1836 *upper_non_critical_going_high = val;
1837 }
1838
1839 if (upper_critical_going_low)
1840 {
1841 if (FIID_OBJ_GET (obj_sdr_record_threshold,
1842 "threshold_deassertion_event_mask.upper_critical_going_low_supported",
1843 &val) < 0)
1844 {
1845 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record_threshold);
1846 goto cleanup;
1847 }
1848 *upper_critical_going_low = val;
1849 }
1850
1851 if (upper_critical_going_high)
1852 {
1853 if (FIID_OBJ_GET (obj_sdr_record_threshold,
1854 "threshold_deassertion_event_mask.upper_critical_going_high_supported",
1855 &val) < 0)
1856 {
1857 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record_threshold);
1858 goto cleanup;
1859 }
1860 *upper_critical_going_high = val;
1861 }
1862
1863 if (upper_non_recoverable_going_low)
1864 {
1865 if (FIID_OBJ_GET (obj_sdr_record_threshold,
1866 "threshold_deassertion_event_mask.upper_non_recoverable_going_low_supported",
1867 &val) < 0)
1868 {
1869 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record_threshold);
1870 goto cleanup;
1871 }
1872 *upper_non_recoverable_going_low = val;
1873 }
1874
1875 if (upper_non_recoverable_going_high)
1876 {
1877 if (FIID_OBJ_GET (obj_sdr_record_threshold,
1878 "threshold_deassertion_event_mask.upper_non_recoverable_going_high_supported",
1879 &val) < 0)
1880 {
1881 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record_threshold);
1882 goto cleanup;
1883 }
1884 *upper_non_recoverable_going_high = val;
1885 }
1886
1887 rv = 0;
1888 ctx->errnum = IPMI_SDR_ERR_SUCCESS;
1889 cleanup:
1890 fiid_obj_destroy (obj_sdr_record);
1891 fiid_obj_destroy (obj_sdr_record_threshold);
1892 return (rv);
1893 }
1894
1895 int
ipmi_sdr_parse_threshold_readable(ipmi_sdr_ctx_t ctx,const void * sdr_record,unsigned int sdr_record_len,uint8_t * lower_non_critical_threshold,uint8_t * lower_critical_threshold,uint8_t * lower_non_recoverable_threshold,uint8_t * upper_non_critical_threshold,uint8_t * upper_critical_threshold,uint8_t * upper_non_recoverable_threshold)1896 ipmi_sdr_parse_threshold_readable (ipmi_sdr_ctx_t ctx,
1897 const void *sdr_record,
1898 unsigned int sdr_record_len,
1899 uint8_t *lower_non_critical_threshold,
1900 uint8_t *lower_critical_threshold,
1901 uint8_t *lower_non_recoverable_threshold,
1902 uint8_t *upper_non_critical_threshold,
1903 uint8_t *upper_critical_threshold,
1904 uint8_t *upper_non_recoverable_threshold)
1905 {
1906 fiid_obj_t obj_sdr_record = NULL;
1907 fiid_obj_t obj_sdr_record_threshold = NULL;
1908 uint32_t acceptable_record_types;
1909 uint8_t event_reading_type_code;
1910 uint64_t val;
1911 int rv = -1;
1912
1913 /* achu:
1914 *
1915 * Technically, the IPMI spec lists that compact record formats also
1916 * support settable thresholds. However, since compact records
1917 * don't contain any information for interpreting threshold sensors
1918 * (e.g. R exponent) I don't know how they could be of any use. No
1919 * vendor that I know of supports threshold sensors via a compact
1920 * record (excluding possible OEM ones).
1921 *
1922 * There's a part of me that believes the readable/setting
1923 * threshold masks for compact sensor records is a cut and paste
1924 * typo. It shouldn't be there.
1925 */
1926
1927 acceptable_record_types = IPMI_SDR_PARSE_RECORD_TYPE_FULL_SENSOR_RECORD;
1928
1929 if (!(obj_sdr_record = _sdr_record_get_common (ctx,
1930 sdr_record,
1931 sdr_record_len,
1932 acceptable_record_types)))
1933 goto cleanup;
1934
1935 /* We don't want the generic sdr full record, we need the special
1936 * threshold one.
1937 */
1938
1939 if (ipmi_sdr_parse_event_reading_type_code (ctx,
1940 sdr_record,
1941 sdr_record_len,
1942 &event_reading_type_code) < 0)
1943 goto cleanup;
1944
1945 if (!IPMI_EVENT_READING_TYPE_CODE_IS_THRESHOLD (event_reading_type_code))
1946 {
1947 SDR_SET_ERRNUM (ctx, IPMI_SDR_ERR_PARSE_INVALID_SDR_RECORD);
1948 goto cleanup;
1949 }
1950
1951 if (!(obj_sdr_record_threshold = fiid_obj_copy (obj_sdr_record,
1952 tmpl_sdr_full_sensor_record_threshold_based_sensors)))
1953 {
1954 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
1955 goto cleanup;
1956 }
1957
1958 if (lower_non_critical_threshold)
1959 {
1960 if (FIID_OBJ_GET (obj_sdr_record_threshold,
1961 "readable_threshold_mask.lower_non_critical_threshold_is_readable",
1962 &val) < 0)
1963 {
1964 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record_threshold);
1965 goto cleanup;
1966 }
1967 *lower_non_critical_threshold = val;
1968 }
1969
1970 if (lower_critical_threshold)
1971 {
1972 if (FIID_OBJ_GET (obj_sdr_record_threshold,
1973 "readable_threshold_mask.lower_critical_threshold_is_readable",
1974 &val) < 0)
1975 {
1976 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record_threshold);
1977 goto cleanup;
1978 }
1979 *lower_critical_threshold = val;
1980 }
1981
1982 if (lower_non_recoverable_threshold)
1983 {
1984 if (FIID_OBJ_GET (obj_sdr_record_threshold,
1985 "readable_threshold_mask.lower_non_recoverable_threshold_is_readable",
1986 &val) < 0)
1987 {
1988 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record_threshold);
1989 goto cleanup;
1990 }
1991 *lower_non_recoverable_threshold = val;
1992 }
1993
1994 if (upper_non_critical_threshold)
1995 {
1996 if (FIID_OBJ_GET (obj_sdr_record_threshold,
1997 "readable_threshold_mask.upper_non_critical_threshold_is_readable",
1998 &val) < 0)
1999 {
2000 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record_threshold);
2001 goto cleanup;
2002 }
2003 *upper_non_critical_threshold = val;
2004 }
2005
2006 if (upper_critical_threshold)
2007 {
2008 if (FIID_OBJ_GET (obj_sdr_record_threshold,
2009 "readable_threshold_mask.upper_critical_threshold_is_readable",
2010 &val) < 0)
2011 {
2012 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record_threshold);
2013 goto cleanup;
2014 }
2015 *upper_critical_threshold = val;
2016 }
2017
2018 if (upper_non_recoverable_threshold)
2019 {
2020 if (FIID_OBJ_GET (obj_sdr_record_threshold,
2021 "readable_threshold_mask.upper_non_recoverable_threshold_is_readable",
2022 &val) < 0)
2023 {
2024 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record_threshold);
2025 goto cleanup;
2026 }
2027 *upper_non_recoverable_threshold = val;
2028 }
2029
2030 rv = 0;
2031 ctx->errnum = IPMI_SDR_ERR_SUCCESS;
2032 cleanup:
2033 fiid_obj_destroy (obj_sdr_record);
2034 fiid_obj_destroy (obj_sdr_record_threshold);
2035 return (rv);
2036 }
2037
2038 int
ipmi_sdr_parse_threshold_settable(ipmi_sdr_ctx_t ctx,const void * sdr_record,unsigned int sdr_record_len,uint8_t * lower_non_critical_threshold,uint8_t * lower_critical_threshold,uint8_t * lower_non_recoverable_threshold,uint8_t * upper_non_critical_threshold,uint8_t * upper_critical_threshold,uint8_t * upper_non_recoverable_threshold)2039 ipmi_sdr_parse_threshold_settable (ipmi_sdr_ctx_t ctx,
2040 const void *sdr_record,
2041 unsigned int sdr_record_len,
2042 uint8_t *lower_non_critical_threshold,
2043 uint8_t *lower_critical_threshold,
2044 uint8_t *lower_non_recoverable_threshold,
2045 uint8_t *upper_non_critical_threshold,
2046 uint8_t *upper_critical_threshold,
2047 uint8_t *upper_non_recoverable_threshold)
2048 {
2049 fiid_obj_t obj_sdr_record = NULL;
2050 fiid_obj_t obj_sdr_record_threshold = NULL;
2051 uint32_t acceptable_record_types;
2052 uint8_t event_reading_type_code;
2053 uint64_t val;
2054 int rv = -1;
2055
2056 /* achu:
2057 *
2058 * Technically, the IPMI spec lists that compact record formats also
2059 * support settable thresholds. However, since compact records
2060 * don't contain any information for interpreting threshold sensors
2061 * (e.g. R exponent) I don't know how they could be of any use. No
2062 * vendor that I know of supports threshold sensors via a compact
2063 * record (excluding possible OEM ones).
2064 *
2065 * There's a part of me that believes the readable/setting
2066 * threshold masks for compact sensor records is a cut and paste
2067 * typo. It shouldn't be there.
2068 */
2069
2070 acceptable_record_types = IPMI_SDR_PARSE_RECORD_TYPE_FULL_SENSOR_RECORD;
2071
2072 if (!(obj_sdr_record = _sdr_record_get_common (ctx,
2073 sdr_record,
2074 sdr_record_len,
2075 acceptable_record_types)))
2076 goto cleanup;
2077
2078 /* We don't want the generic sdr full record, we need the special
2079 * threshold one.
2080 */
2081
2082 if (ipmi_sdr_parse_event_reading_type_code (ctx,
2083 sdr_record,
2084 sdr_record_len,
2085 &event_reading_type_code) < 0)
2086 goto cleanup;
2087
2088 if (!IPMI_EVENT_READING_TYPE_CODE_IS_THRESHOLD (event_reading_type_code))
2089 {
2090 SDR_SET_ERRNUM (ctx, IPMI_SDR_ERR_PARSE_INVALID_SDR_RECORD);
2091 goto cleanup;
2092 }
2093
2094 if (!(obj_sdr_record_threshold = fiid_obj_copy (obj_sdr_record,
2095 tmpl_sdr_full_sensor_record_threshold_based_sensors)))
2096 {
2097 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
2098 goto cleanup;
2099 }
2100
2101 if (lower_non_critical_threshold)
2102 {
2103 if (FIID_OBJ_GET (obj_sdr_record_threshold,
2104 "settable_threshold_mask.lower_non_critical_threshold_is_settable",
2105 &val) < 0)
2106 {
2107 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record_threshold);
2108 goto cleanup;
2109 }
2110 *lower_non_critical_threshold = val;
2111 }
2112
2113 if (lower_critical_threshold)
2114 {
2115 if (FIID_OBJ_GET (obj_sdr_record_threshold,
2116 "settable_threshold_mask.lower_critical_threshold_is_settable",
2117 &val) < 0)
2118 {
2119 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record_threshold);
2120 goto cleanup;
2121 }
2122 *lower_critical_threshold = val;
2123 }
2124
2125 if (lower_non_recoverable_threshold)
2126 {
2127 if (FIID_OBJ_GET (obj_sdr_record_threshold,
2128 "settable_threshold_mask.lower_non_recoverable_threshold_is_settable",
2129 &val) < 0)
2130 {
2131 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record_threshold);
2132 goto cleanup;
2133 }
2134 *lower_non_recoverable_threshold = val;
2135 }
2136
2137 if (upper_non_critical_threshold)
2138 {
2139 if (FIID_OBJ_GET (obj_sdr_record_threshold,
2140 "settable_threshold_mask.upper_non_critical_threshold_is_settable",
2141 &val) < 0)
2142 {
2143 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record_threshold);
2144 goto cleanup;
2145 }
2146 *upper_non_critical_threshold = val;
2147 }
2148
2149 if (upper_critical_threshold)
2150 {
2151 if (FIID_OBJ_GET (obj_sdr_record_threshold,
2152 "settable_threshold_mask.upper_critical_threshold_is_settable",
2153 &val) < 0)
2154 {
2155 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record_threshold);
2156 goto cleanup;
2157 }
2158 *upper_critical_threshold = val;
2159 }
2160
2161 if (upper_non_recoverable_threshold)
2162 {
2163 if (FIID_OBJ_GET (obj_sdr_record_threshold,
2164 "settable_threshold_mask.upper_non_recoverable_threshold_is_settable",
2165 &val) < 0)
2166 {
2167 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record_threshold);
2168 goto cleanup;
2169 }
2170 *upper_non_recoverable_threshold = val;
2171 }
2172
2173 rv = 0;
2174 ctx->errnum = IPMI_SDR_ERR_SUCCESS;
2175 cleanup:
2176 fiid_obj_destroy (obj_sdr_record);
2177 fiid_obj_destroy (obj_sdr_record_threshold);
2178 return (rv);
2179 }
2180
2181 int
ipmi_sdr_parse_sensor_decoding_data(ipmi_sdr_ctx_t ctx,const void * sdr_record,unsigned int sdr_record_len,int8_t * r_exponent,int8_t * b_exponent,int16_t * m,int16_t * b,uint8_t * linearization,uint8_t * analog_data_format)2182 ipmi_sdr_parse_sensor_decoding_data (ipmi_sdr_ctx_t ctx,
2183 const void *sdr_record,
2184 unsigned int sdr_record_len,
2185 int8_t *r_exponent,
2186 int8_t *b_exponent,
2187 int16_t *m,
2188 int16_t *b,
2189 uint8_t *linearization,
2190 uint8_t *analog_data_format)
2191 {
2192 fiid_obj_t obj_sdr_record = NULL;
2193 uint32_t acceptable_record_types;
2194 uint64_t val, val1, val2;
2195 int rv = -1;
2196
2197 acceptable_record_types = IPMI_SDR_PARSE_RECORD_TYPE_FULL_SENSOR_RECORD;
2198
2199 if (!(obj_sdr_record = _sdr_record_get_common (ctx,
2200 sdr_record,
2201 sdr_record_len,
2202 acceptable_record_types)))
2203 goto cleanup;
2204
2205 if (r_exponent)
2206 {
2207 if (FIID_OBJ_GET (obj_sdr_record,
2208 "r_exponent",
2209 &val) < 0)
2210 {
2211 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
2212 goto cleanup;
2213 }
2214 *r_exponent = val;
2215 if (*r_exponent & 0x08)
2216 *r_exponent |= 0xF0;
2217 }
2218
2219 if (b_exponent)
2220 {
2221 if (FIID_OBJ_GET (obj_sdr_record,
2222 "b_exponent",
2223 &val) < 0)
2224 {
2225 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
2226 goto cleanup;
2227 }
2228 *b_exponent = val;
2229 if (*b_exponent & 0x08)
2230 *b_exponent |= 0xF0;
2231 }
2232
2233 if (m)
2234 {
2235 if (FIID_OBJ_GET (obj_sdr_record,
2236 "m_ls",
2237 &val1) < 0)
2238 {
2239 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
2240 goto cleanup;
2241 }
2242 if (FIID_OBJ_GET (obj_sdr_record,
2243 "m_ms",
2244 &val2) < 0)
2245 {
2246 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
2247 goto cleanup;
2248 }
2249 *m = val1;
2250 *m |= (((int16_t)val2 & 0x3) << 8);
2251 if (*m & 0x200)
2252 *m |= 0xFE00;
2253 }
2254
2255 if (b)
2256 {
2257 if (FIID_OBJ_GET (obj_sdr_record,
2258 "b_ls",
2259 &val1) < 0)
2260 {
2261 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
2262 goto cleanup;
2263 }
2264 if (FIID_OBJ_GET (obj_sdr_record,
2265 "b_ms",
2266 &val2) < 0)
2267 {
2268 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
2269 goto cleanup;
2270 }
2271 *b = val1;
2272 *b |= (((int16_t)val2 & 0x3) << 8);
2273 if (*b & 0x200)
2274 *b |= 0xFE00;
2275 }
2276
2277 if (linearization)
2278 {
2279 if (FIID_OBJ_GET (obj_sdr_record,
2280 "linearization",
2281 &val) < 0)
2282 {
2283 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
2284 goto cleanup;
2285 }
2286 (*linearization) = val;
2287 }
2288
2289 if (analog_data_format)
2290 {
2291 if (FIID_OBJ_GET (obj_sdr_record,
2292 "sensor_unit1.analog_data_format",
2293 &val) < 0)
2294 {
2295 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
2296 goto cleanup;
2297 }
2298 (*analog_data_format) = val;
2299 }
2300
2301 rv = 0;
2302 ctx->errnum = IPMI_SDR_ERR_SUCCESS;
2303 cleanup:
2304 fiid_obj_destroy (obj_sdr_record);
2305 return (rv);
2306 }
2307
2308 static int
_sensor_decode_value(ipmi_sdr_ctx_t ctx,int8_t r_exponent,int8_t b_exponent,int16_t m,int16_t b,uint8_t linearization,uint8_t analog_data_format,uint8_t raw_data,double ** value_ptr)2309 _sensor_decode_value (ipmi_sdr_ctx_t ctx,
2310 int8_t r_exponent,
2311 int8_t b_exponent,
2312 int16_t m,
2313 int16_t b,
2314 uint8_t linearization,
2315 uint8_t analog_data_format,
2316 uint8_t raw_data,
2317 double **value_ptr)
2318 {
2319 double reading;
2320 int rv = -1;
2321
2322 assert (ctx);
2323 assert (ctx->magic == IPMI_SDR_CTX_MAGIC);
2324 assert (value_ptr);
2325
2326 *value_ptr = NULL;
2327
2328 if (ipmi_sensor_decode_value (r_exponent,
2329 b_exponent,
2330 m,
2331 b,
2332 linearization,
2333 analog_data_format,
2334 raw_data,
2335 &reading) < 0)
2336 {
2337 SDR_SET_ERRNUM (ctx, IPMI_SDR_ERR_INTERNAL_ERROR);
2338 goto cleanup;
2339 }
2340
2341 if (!((*value_ptr) = (double *)malloc (sizeof (double))))
2342 {
2343 SDR_SET_ERRNUM (ctx, IPMI_SDR_ERR_OUT_OF_MEMORY);
2344 goto cleanup;
2345 }
2346 (**value_ptr) = reading;
2347
2348 rv = 0;
2349 cleanup:
2350 return (rv);
2351 }
2352
2353 int
ipmi_sdr_parse_sensor_reading_ranges_specified(ipmi_sdr_ctx_t ctx,const void * sdr_record,unsigned int sdr_record_len,uint8_t * nominal_reading_specified,uint8_t * normal_maximum_specified,uint8_t * normal_minimum_specified)2354 ipmi_sdr_parse_sensor_reading_ranges_specified (ipmi_sdr_ctx_t ctx,
2355 const void *sdr_record,
2356 unsigned int sdr_record_len,
2357 uint8_t *nominal_reading_specified,
2358 uint8_t *normal_maximum_specified,
2359 uint8_t *normal_minimum_specified)
2360 {
2361 fiid_obj_t obj_sdr_record = NULL;
2362 uint32_t acceptable_record_types;
2363 uint64_t val;
2364 int rv = -1;
2365
2366 acceptable_record_types = IPMI_SDR_PARSE_RECORD_TYPE_FULL_SENSOR_RECORD;
2367
2368 if (!(obj_sdr_record = _sdr_record_get_common (ctx,
2369 sdr_record,
2370 sdr_record_len,
2371 acceptable_record_types)))
2372 goto cleanup;
2373
2374 if (nominal_reading_specified)
2375 {
2376 if (FIID_OBJ_GET (obj_sdr_record,
2377 "analog_characteristics_flag.nominal_reading",
2378 &val) < 0)
2379 {
2380 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
2381 goto cleanup;
2382 }
2383 *nominal_reading_specified = val;
2384 }
2385
2386 if (normal_maximum_specified)
2387 {
2388 if (FIID_OBJ_GET (obj_sdr_record,
2389 "analog_characteristics_flag.normal_max",
2390 &val) < 0)
2391 {
2392 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
2393 goto cleanup;
2394 }
2395 *normal_maximum_specified = val;
2396 }
2397
2398 if (normal_minimum_specified)
2399 {
2400 if (FIID_OBJ_GET (obj_sdr_record,
2401 "analog_characteristics_flag.normal_min",
2402 &val) < 0)
2403 {
2404 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
2405 goto cleanup;
2406 }
2407 *normal_minimum_specified = val;
2408 }
2409
2410 rv = 0;
2411 ctx->errnum = IPMI_SDR_ERR_SUCCESS;
2412 cleanup:
2413 fiid_obj_destroy (obj_sdr_record);
2414 return (rv);
2415 }
2416
2417 int
ipmi_sdr_parse_sensor_reading_ranges(ipmi_sdr_ctx_t ctx,const void * sdr_record,unsigned int sdr_record_len,double ** nominal_reading,double ** normal_maximum,double ** normal_minimum,double ** sensor_maximum_reading,double ** sensor_minimum_reading)2418 ipmi_sdr_parse_sensor_reading_ranges (ipmi_sdr_ctx_t ctx,
2419 const void *sdr_record,
2420 unsigned int sdr_record_len,
2421 double **nominal_reading,
2422 double **normal_maximum,
2423 double **normal_minimum,
2424 double **sensor_maximum_reading,
2425 double **sensor_minimum_reading)
2426 {
2427 fiid_obj_t obj_sdr_record = NULL;
2428 uint32_t acceptable_record_types;
2429 int8_t r_exponent, b_exponent;
2430 int16_t m, b;
2431 uint8_t reading_raw, linearization, analog_data_format;
2432 double *tmp_nominal_reading = NULL;
2433 double *tmp_normal_maximum = NULL;
2434 double *tmp_normal_minimum = NULL;
2435 double *tmp_sensor_maximum_reading = NULL;
2436 double *tmp_sensor_minimum_reading = NULL;
2437 uint64_t val;
2438 int rv = -1;
2439
2440 acceptable_record_types = IPMI_SDR_PARSE_RECORD_TYPE_FULL_SENSOR_RECORD;
2441
2442 if (!(obj_sdr_record = _sdr_record_get_common (ctx,
2443 sdr_record,
2444 sdr_record_len,
2445 acceptable_record_types)))
2446 goto cleanup;
2447
2448 if (nominal_reading)
2449 *nominal_reading = NULL;
2450 if (normal_maximum)
2451 *normal_maximum = NULL;
2452 if (normal_minimum)
2453 *normal_minimum = NULL;
2454 if (sensor_maximum_reading)
2455 *sensor_maximum_reading = NULL;
2456 if (sensor_minimum_reading)
2457 *sensor_minimum_reading = NULL;
2458
2459 if (ipmi_sdr_parse_sensor_decoding_data (ctx,
2460 sdr_record,
2461 sdr_record_len,
2462 &r_exponent,
2463 &b_exponent,
2464 &m,
2465 &b,
2466 &linearization,
2467 &analog_data_format) < 0)
2468 goto cleanup;
2469
2470 if (!IPMI_SDR_ANALOG_DATA_FORMAT_VALID (analog_data_format))
2471 {
2472 SDR_SET_ERRNUM (ctx, IPMI_SDR_ERR_PARSE_CANNOT_PARSE_OR_CALCULATE);
2473 goto cleanup;
2474 }
2475
2476 if (!IPMI_SDR_LINEARIZATION_IS_LINEAR (linearization))
2477 {
2478 SDR_SET_ERRNUM (ctx, IPMI_SDR_ERR_PARSE_CANNOT_PARSE_OR_CALCULATE);
2479 goto cleanup;
2480 }
2481
2482 if (nominal_reading)
2483 {
2484 if (FIID_OBJ_GET (obj_sdr_record,
2485 "nominal_reading",
2486 &val) < 0)
2487 {
2488 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
2489 goto cleanup;
2490 }
2491 reading_raw = val;
2492
2493 if (_sensor_decode_value (ctx,
2494 r_exponent,
2495 b_exponent,
2496 m,
2497 b,
2498 linearization,
2499 analog_data_format,
2500 reading_raw,
2501 &tmp_nominal_reading) < 0)
2502 goto cleanup;
2503 }
2504 if (normal_maximum)
2505 {
2506 if (FIID_OBJ_GET (obj_sdr_record,
2507 "normal_maximum",
2508 &val) < 0)
2509 {
2510 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
2511 goto cleanup;
2512 }
2513 reading_raw = val;
2514
2515 if (_sensor_decode_value (ctx,
2516 r_exponent,
2517 b_exponent,
2518 m,
2519 b,
2520 linearization,
2521 analog_data_format,
2522 reading_raw,
2523 &tmp_normal_maximum) < 0)
2524 goto cleanup;
2525 }
2526 if (normal_minimum)
2527 {
2528 if (FIID_OBJ_GET (obj_sdr_record,
2529 "normal_minimum",
2530 &val) < 0)
2531 {
2532 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
2533 goto cleanup;
2534 }
2535 reading_raw = val;
2536
2537 if (_sensor_decode_value (ctx,
2538 r_exponent,
2539 b_exponent,
2540 m,
2541 b,
2542 linearization,
2543 analog_data_format,
2544 reading_raw,
2545 &tmp_normal_minimum) < 0)
2546 goto cleanup;
2547 }
2548 if (sensor_maximum_reading)
2549 {
2550 if (FIID_OBJ_GET (obj_sdr_record,
2551 "sensor_maximum_reading",
2552 &val) < 0)
2553 {
2554 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
2555 goto cleanup;
2556 }
2557 reading_raw = val;
2558
2559 if (_sensor_decode_value (ctx,
2560 r_exponent,
2561 b_exponent,
2562 m,
2563 b,
2564 linearization,
2565 analog_data_format,
2566 reading_raw,
2567 &tmp_sensor_maximum_reading) < 0)
2568 goto cleanup;
2569 }
2570 if (sensor_minimum_reading)
2571 {
2572 if (FIID_OBJ_GET (obj_sdr_record,
2573 "sensor_minimum_reading",
2574 &val) < 0)
2575 {
2576 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
2577 goto cleanup;
2578 }
2579 reading_raw = val;
2580
2581 if (_sensor_decode_value (ctx,
2582 r_exponent,
2583 b_exponent,
2584 m,
2585 b,
2586 linearization,
2587 analog_data_format,
2588 reading_raw,
2589 &tmp_sensor_minimum_reading) < 0)
2590 goto cleanup;
2591 }
2592
2593 if (nominal_reading)
2594 *nominal_reading = tmp_nominal_reading;
2595 if (normal_maximum)
2596 *normal_maximum = tmp_normal_maximum;
2597 if (normal_minimum)
2598 *normal_minimum = tmp_normal_minimum;
2599 if (sensor_maximum_reading)
2600 *sensor_maximum_reading = tmp_sensor_maximum_reading;
2601 if (sensor_minimum_reading)
2602 *sensor_minimum_reading = tmp_sensor_minimum_reading;
2603
2604 rv = 0;
2605 ctx->errnum = IPMI_SDR_ERR_SUCCESS;
2606 cleanup:
2607 fiid_obj_destroy (obj_sdr_record);
2608 if (rv < 0)
2609 {
2610 free (tmp_nominal_reading);
2611 free (tmp_normal_maximum);
2612 free (tmp_normal_minimum);
2613 free (tmp_sensor_maximum_reading);
2614 free (tmp_sensor_minimum_reading);
2615 }
2616 return (rv);
2617 }
2618
2619 int
ipmi_sdr_parse_thresholds(ipmi_sdr_ctx_t ctx,const void * sdr_record,unsigned int sdr_record_len,double ** lower_non_critical_threshold,double ** lower_critical_threshold,double ** lower_non_recoverable_threshold,double ** upper_non_critical_threshold,double ** upper_critical_threshold,double ** upper_non_recoverable_threshold)2620 ipmi_sdr_parse_thresholds (ipmi_sdr_ctx_t ctx,
2621 const void *sdr_record,
2622 unsigned int sdr_record_len,
2623 double **lower_non_critical_threshold,
2624 double **lower_critical_threshold,
2625 double **lower_non_recoverable_threshold,
2626 double **upper_non_critical_threshold,
2627 double **upper_critical_threshold,
2628 double **upper_non_recoverable_threshold)
2629 {
2630 fiid_obj_t obj_sdr_record = NULL;
2631 uint32_t acceptable_record_types;
2632 int8_t r_exponent, b_exponent;
2633 int16_t m, b;
2634 uint8_t threshold_raw, linearization, analog_data_format;
2635 double *tmp_lower_non_critical_threshold = NULL;
2636 double *tmp_lower_critical_threshold = NULL;
2637 double *tmp_lower_non_recoverable_threshold = NULL;
2638 double *tmp_upper_non_critical_threshold = NULL;
2639 double *tmp_upper_critical_threshold = NULL;
2640 double *tmp_upper_non_recoverable_threshold = NULL;
2641 uint64_t val;
2642 int rv = -1;
2643
2644 acceptable_record_types = IPMI_SDR_PARSE_RECORD_TYPE_FULL_SENSOR_RECORD;
2645
2646 if (!(obj_sdr_record = _sdr_record_get_common (ctx,
2647 sdr_record,
2648 sdr_record_len,
2649 acceptable_record_types)))
2650 goto cleanup;
2651
2652 if (lower_non_critical_threshold)
2653 *lower_non_critical_threshold = NULL;
2654 if (lower_critical_threshold)
2655 *lower_critical_threshold = NULL;
2656 if (lower_non_recoverable_threshold)
2657 *lower_non_recoverable_threshold = NULL;
2658 if (upper_non_critical_threshold)
2659 *upper_non_critical_threshold = NULL;
2660 if (upper_critical_threshold)
2661 *upper_critical_threshold = NULL;
2662 if (upper_non_recoverable_threshold)
2663 *upper_non_recoverable_threshold = NULL;
2664
2665 if (ipmi_sdr_parse_sensor_decoding_data (ctx,
2666 sdr_record,
2667 sdr_record_len,
2668 &r_exponent,
2669 &b_exponent,
2670 &m,
2671 &b,
2672 &linearization,
2673 &analog_data_format) < 0)
2674 goto cleanup;
2675
2676 if (!IPMI_SDR_ANALOG_DATA_FORMAT_VALID (analog_data_format))
2677 {
2678 SDR_SET_ERRNUM (ctx, IPMI_SDR_ERR_PARSE_CANNOT_PARSE_OR_CALCULATE);
2679 goto cleanup;
2680 }
2681
2682 if (!IPMI_SDR_LINEARIZATION_IS_LINEAR (linearization))
2683 {
2684 SDR_SET_ERRNUM (ctx, IPMI_SDR_ERR_PARSE_CANNOT_PARSE_OR_CALCULATE);
2685 goto cleanup;
2686 }
2687
2688 if (lower_non_critical_threshold)
2689 {
2690 if (FIID_OBJ_GET (obj_sdr_record,
2691 "lower_non_critical_threshold",
2692 &val) < 0)
2693 {
2694 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
2695 goto cleanup;
2696 }
2697 threshold_raw = val;
2698
2699 if (_sensor_decode_value (ctx,
2700 r_exponent,
2701 b_exponent,
2702 m,
2703 b,
2704 linearization,
2705 analog_data_format,
2706 threshold_raw,
2707 &tmp_lower_non_critical_threshold) < 0)
2708 goto cleanup;
2709 }
2710 if (lower_critical_threshold)
2711 {
2712 if (FIID_OBJ_GET (obj_sdr_record,
2713 "lower_critical_threshold",
2714 &val) < 0)
2715 {
2716 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
2717 goto cleanup;
2718 }
2719 threshold_raw = val;
2720
2721 if (_sensor_decode_value (ctx,
2722 r_exponent,
2723 b_exponent,
2724 m,
2725 b,
2726 linearization,
2727 analog_data_format,
2728 threshold_raw,
2729 &tmp_lower_critical_threshold) < 0)
2730 goto cleanup;
2731 }
2732 if (lower_non_recoverable_threshold)
2733 {
2734 if (FIID_OBJ_GET (obj_sdr_record,
2735 "lower_non_recoverable_threshold",
2736 &val) < 0)
2737 {
2738 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
2739 goto cleanup;
2740 }
2741 threshold_raw = val;
2742
2743 if (_sensor_decode_value (ctx,
2744 r_exponent,
2745 b_exponent,
2746 m,
2747 b,
2748 linearization,
2749 analog_data_format,
2750 threshold_raw,
2751 &tmp_lower_non_recoverable_threshold) < 0)
2752 goto cleanup;
2753 }
2754 if (upper_non_critical_threshold)
2755 {
2756 if (FIID_OBJ_GET (obj_sdr_record,
2757 "upper_non_critical_threshold",
2758 &val) < 0)
2759 {
2760 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
2761 goto cleanup;
2762 }
2763 threshold_raw = val;
2764
2765 if (_sensor_decode_value (ctx,
2766 r_exponent,
2767 b_exponent,
2768 m,
2769 b,
2770 linearization,
2771 analog_data_format,
2772 threshold_raw,
2773 &tmp_upper_non_critical_threshold) < 0)
2774 goto cleanup;
2775 }
2776 if (upper_critical_threshold)
2777 {
2778 if (FIID_OBJ_GET (obj_sdr_record,
2779 "upper_critical_threshold",
2780 &val) < 0)
2781 {
2782 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
2783 goto cleanup;
2784 }
2785 threshold_raw = val;
2786
2787 if (_sensor_decode_value (ctx,
2788 r_exponent,
2789 b_exponent,
2790 m,
2791 b,
2792 linearization,
2793 analog_data_format,
2794 threshold_raw,
2795 &tmp_upper_critical_threshold) < 0)
2796 goto cleanup;
2797 }
2798 if (upper_non_recoverable_threshold)
2799 {
2800 if (FIID_OBJ_GET (obj_sdr_record,
2801 "upper_non_recoverable_threshold",
2802 &val) < 0)
2803 {
2804 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
2805 goto cleanup;
2806 }
2807 threshold_raw = val;
2808
2809 if (_sensor_decode_value (ctx,
2810 r_exponent,
2811 b_exponent,
2812 m,
2813 b,
2814 linearization,
2815 analog_data_format,
2816 threshold_raw,
2817 &tmp_upper_non_recoverable_threshold) < 0)
2818 goto cleanup;
2819 }
2820
2821 if (lower_non_critical_threshold)
2822 *lower_non_critical_threshold = tmp_lower_non_critical_threshold;
2823 if (lower_critical_threshold)
2824 *lower_critical_threshold = tmp_lower_critical_threshold;
2825 if (lower_non_recoverable_threshold)
2826 *lower_non_recoverable_threshold = tmp_lower_non_recoverable_threshold;
2827 if (upper_non_critical_threshold)
2828 *upper_non_critical_threshold = tmp_upper_non_critical_threshold;
2829 if (upper_critical_threshold)
2830 *upper_critical_threshold = tmp_upper_critical_threshold;
2831 if (upper_non_recoverable_threshold)
2832 *upper_non_recoverable_threshold = tmp_upper_non_recoverable_threshold;
2833
2834 rv = 0;
2835 ctx->errnum = IPMI_SDR_ERR_SUCCESS;
2836 cleanup:
2837 fiid_obj_destroy (obj_sdr_record);
2838 if (rv < 0)
2839 {
2840 free (tmp_lower_non_critical_threshold);
2841 free (tmp_lower_critical_threshold);
2842 free (tmp_lower_non_recoverable_threshold);
2843 free (tmp_upper_non_critical_threshold);
2844 free (tmp_upper_critical_threshold);
2845 free (tmp_upper_non_recoverable_threshold);
2846 }
2847 return (rv);
2848 }
2849
2850 int
ipmi_sdr_parse_thresholds_raw(ipmi_sdr_ctx_t ctx,const void * sdr_record,unsigned int sdr_record_len,uint8_t * lower_non_critical_threshold,uint8_t * lower_critical_threshold,uint8_t * lower_non_recoverable_threshold,uint8_t * upper_non_critical_threshold,uint8_t * upper_critical_threshold,uint8_t * upper_non_recoverable_threshold)2851 ipmi_sdr_parse_thresholds_raw (ipmi_sdr_ctx_t ctx,
2852 const void *sdr_record,
2853 unsigned int sdr_record_len,
2854 uint8_t *lower_non_critical_threshold,
2855 uint8_t *lower_critical_threshold,
2856 uint8_t *lower_non_recoverable_threshold,
2857 uint8_t *upper_non_critical_threshold,
2858 uint8_t *upper_critical_threshold,
2859 uint8_t *upper_non_recoverable_threshold)
2860 {
2861 fiid_obj_t obj_sdr_record = NULL;
2862 fiid_obj_t obj_sdr_record_threshold = NULL;
2863 uint32_t acceptable_record_types;
2864 uint8_t event_reading_type_code;
2865 uint64_t val;
2866 int rv = -1;
2867
2868 acceptable_record_types = IPMI_SDR_PARSE_RECORD_TYPE_FULL_SENSOR_RECORD;
2869
2870 if (!(obj_sdr_record = _sdr_record_get_common (ctx,
2871 sdr_record,
2872 sdr_record_len,
2873 acceptable_record_types)))
2874 goto cleanup;
2875
2876 /* We don't want the generic sdr full record, we need the special
2877 * threshold one.
2878 */
2879
2880 if (ipmi_sdr_parse_event_reading_type_code (ctx,
2881 sdr_record,
2882 sdr_record_len,
2883 &event_reading_type_code) < 0)
2884 goto cleanup;
2885
2886 if (!IPMI_EVENT_READING_TYPE_CODE_IS_THRESHOLD (event_reading_type_code))
2887 {
2888 SDR_SET_ERRNUM (ctx, IPMI_SDR_ERR_PARSE_INVALID_SDR_RECORD);
2889 goto cleanup;
2890 }
2891
2892 if (!(obj_sdr_record_threshold = fiid_obj_copy (obj_sdr_record,
2893 tmpl_sdr_full_sensor_record_threshold_based_sensors)))
2894 {
2895 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
2896 goto cleanup;
2897 }
2898
2899 if (lower_non_critical_threshold)
2900 {
2901 if (FIID_OBJ_GET (obj_sdr_record_threshold,
2902 "lower_non_critical_threshold",
2903 &val) < 0)
2904 {
2905 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record_threshold);
2906 goto cleanup;
2907 }
2908 *lower_non_critical_threshold = val;
2909 }
2910
2911 if (lower_critical_threshold)
2912 {
2913 if (FIID_OBJ_GET (obj_sdr_record_threshold,
2914 "lower_critical_threshold",
2915 &val) < 0)
2916 {
2917 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record_threshold);
2918 goto cleanup;
2919 }
2920 *lower_critical_threshold = val;
2921 }
2922
2923 if (lower_non_recoverable_threshold)
2924 {
2925 if (FIID_OBJ_GET (obj_sdr_record_threshold,
2926 "lower_non_recoverable_threshold",
2927 &val) < 0)
2928 {
2929 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record_threshold);
2930 goto cleanup;
2931 }
2932 *lower_non_recoverable_threshold = val;
2933 }
2934
2935 if (upper_non_critical_threshold)
2936 {
2937 if (FIID_OBJ_GET (obj_sdr_record_threshold,
2938 "upper_non_critical_threshold",
2939 &val) < 0)
2940 {
2941 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record_threshold);
2942 goto cleanup;
2943 }
2944 *upper_non_critical_threshold = val;
2945 }
2946
2947 if (upper_critical_threshold)
2948 {
2949 if (FIID_OBJ_GET (obj_sdr_record_threshold,
2950 "upper_critical_threshold",
2951 &val) < 0)
2952 {
2953 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record_threshold);
2954 goto cleanup;
2955 }
2956 *upper_critical_threshold = val;
2957 }
2958
2959 if (upper_non_recoverable_threshold)
2960 {
2961 if (FIID_OBJ_GET (obj_sdr_record_threshold,
2962 "upper_non_recoverable_threshold",
2963 &val) < 0)
2964 {
2965 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record_threshold);
2966 goto cleanup;
2967 }
2968 *upper_non_recoverable_threshold = val;
2969 }
2970
2971 rv = 0;
2972 ctx->errnum = IPMI_SDR_ERR_SUCCESS;
2973 cleanup:
2974 fiid_obj_destroy (obj_sdr_record);
2975 fiid_obj_destroy (obj_sdr_record_threshold);
2976 return (rv);
2977 }
2978
2979 int
ipmi_sdr_parse_tolerance(ipmi_sdr_ctx_t ctx,const void * sdr_record,unsigned int sdr_record_len,double ** tolerance)2980 ipmi_sdr_parse_tolerance (ipmi_sdr_ctx_t ctx,
2981 const void *sdr_record,
2982 unsigned int sdr_record_len,
2983 double **tolerance)
2984 {
2985 fiid_obj_t obj_sdr_record = NULL;
2986 uint32_t acceptable_record_types;
2987 int8_t r_exponent;
2988 int16_t m;
2989 uint8_t tolerance_raw, linearization;
2990 double *tmp_tolerance = NULL;
2991 uint64_t val;
2992 int rv = -1;
2993
2994 acceptable_record_types = IPMI_SDR_PARSE_RECORD_TYPE_FULL_SENSOR_RECORD;
2995
2996 if (!(obj_sdr_record = _sdr_record_get_common (ctx,
2997 sdr_record,
2998 sdr_record_len,
2999 acceptable_record_types)))
3000 goto cleanup;
3001
3002 if (tolerance)
3003 *tolerance = NULL;
3004
3005 if (ipmi_sdr_parse_sensor_decoding_data (ctx,
3006 sdr_record,
3007 sdr_record_len,
3008 &r_exponent,
3009 NULL,
3010 &m,
3011 NULL,
3012 &linearization,
3013 NULL) < 0)
3014 goto cleanup;
3015
3016 if (!IPMI_SDR_LINEARIZATION_IS_LINEAR (linearization))
3017 {
3018 SDR_SET_ERRNUM (ctx, IPMI_SDR_ERR_PARSE_CANNOT_PARSE_OR_CALCULATE);
3019 goto cleanup;
3020 }
3021
3022 if (tolerance)
3023 {
3024 double reading;
3025
3026 if (FIID_OBJ_GET (obj_sdr_record,
3027 "tolerance",
3028 &val) < 0)
3029 {
3030 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
3031 goto cleanup;
3032 }
3033 tolerance_raw = val;
3034
3035 if (ipmi_sensor_decode_tolerance (r_exponent,
3036 m,
3037 linearization,
3038 tolerance_raw,
3039 &reading) < 0)
3040 {
3041 SDR_SET_ERRNUM (ctx, IPMI_SDR_ERR_INTERNAL_ERROR);
3042 goto cleanup;
3043 }
3044
3045 if (!(tmp_tolerance = (double *)malloc (sizeof (double))))
3046 {
3047 SDR_SET_ERRNUM (ctx, IPMI_SDR_ERR_OUT_OF_MEMORY);
3048 goto cleanup;
3049 }
3050 (*tmp_tolerance) = reading;
3051 }
3052
3053 if (tolerance)
3054 *tolerance = tmp_tolerance;
3055
3056 rv = 0;
3057 ctx->errnum = IPMI_SDR_ERR_SUCCESS;
3058 cleanup:
3059 fiid_obj_destroy (obj_sdr_record);
3060 if (rv < 0)
3061 free (tmp_tolerance);
3062 return (rv);
3063 }
3064
3065 int
ipmi_sdr_parse_accuracy(ipmi_sdr_ctx_t ctx,const void * sdr_record,unsigned int sdr_record_len,double ** accuracy)3066 ipmi_sdr_parse_accuracy (ipmi_sdr_ctx_t ctx,
3067 const void *sdr_record,
3068 unsigned int sdr_record_len,
3069 double **accuracy)
3070 {
3071 fiid_obj_t obj_sdr_record = NULL;
3072 uint32_t acceptable_record_types;
3073 uint16_t accuracy_raw;
3074 uint8_t accuracy_ls, accuracy_ms, accuracy_exp;
3075 double *tmp_accuracy = NULL;
3076 uint64_t val;
3077 int rv = -1;
3078
3079 acceptable_record_types = IPMI_SDR_PARSE_RECORD_TYPE_FULL_SENSOR_RECORD;
3080
3081 if (!(obj_sdr_record = _sdr_record_get_common (ctx,
3082 sdr_record,
3083 sdr_record_len,
3084 acceptable_record_types)))
3085 goto cleanup;
3086
3087 if (accuracy)
3088 *accuracy = NULL;
3089
3090 if (accuracy)
3091 {
3092 double reading;
3093
3094 if (FIID_OBJ_GET (obj_sdr_record,
3095 "accuracy_ls",
3096 &val) < 0)
3097 {
3098 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
3099 goto cleanup;
3100 }
3101 accuracy_ls = val;
3102
3103 if (FIID_OBJ_GET (obj_sdr_record,
3104 "accuracy_ms",
3105 &val) < 0)
3106 {
3107 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
3108 goto cleanup;
3109 }
3110 accuracy_ms = val;
3111
3112 /* accuracy is unsigned, no need to sign extend */
3113 accuracy_raw = accuracy_ls | (((uint16_t)accuracy_ms) << 6);
3114
3115 if (FIID_OBJ_GET (obj_sdr_record,
3116 "accuracy_exp",
3117 &val) < 0)
3118 {
3119 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
3120 goto cleanup;
3121 }
3122 accuracy_exp = val;
3123
3124 if (ipmi_sensor_decode_accuracy (accuracy_raw,
3125 accuracy_exp,
3126 &reading) < 0)
3127 {
3128 SDR_SET_ERRNUM (ctx, IPMI_SDR_ERR_INTERNAL_ERROR);
3129 goto cleanup;
3130 }
3131
3132 if (!(tmp_accuracy = (double *)malloc (sizeof (double))))
3133 {
3134 SDR_SET_ERRNUM (ctx, IPMI_SDR_ERR_OUT_OF_MEMORY);
3135 goto cleanup;
3136 }
3137 (*tmp_accuracy) = reading;
3138 }
3139
3140 if (accuracy)
3141 *accuracy = tmp_accuracy;
3142
3143 rv = 0;
3144 ctx->errnum = IPMI_SDR_ERR_SUCCESS;
3145 cleanup:
3146 fiid_obj_destroy (obj_sdr_record);
3147 if (rv < 0)
3148 free (tmp_accuracy);
3149 return (rv);
3150 }
3151
3152 int
ipmi_sdr_parse_hysteresis(ipmi_sdr_ctx_t ctx,const void * sdr_record,unsigned int sdr_record_len,uint8_t * positive_going_threshold_hysteresis,uint8_t * negative_going_threshold_hysteresis)3153 ipmi_sdr_parse_hysteresis (ipmi_sdr_ctx_t ctx,
3154 const void *sdr_record,
3155 unsigned int sdr_record_len,
3156 uint8_t *positive_going_threshold_hysteresis,
3157 uint8_t *negative_going_threshold_hysteresis)
3158 {
3159 fiid_obj_t obj_sdr_record = NULL;
3160 uint32_t acceptable_record_types;
3161 uint64_t val;
3162 int rv = -1;
3163
3164 acceptable_record_types = IPMI_SDR_PARSE_RECORD_TYPE_FULL_SENSOR_RECORD;
3165 acceptable_record_types |= IPMI_SDR_PARSE_RECORD_TYPE_COMPACT_SENSOR_RECORD;
3166
3167 if (!(obj_sdr_record = _sdr_record_get_common (ctx,
3168 sdr_record,
3169 sdr_record_len,
3170 acceptable_record_types)))
3171 goto cleanup;
3172
3173 if (positive_going_threshold_hysteresis)
3174 {
3175 if (FIID_OBJ_GET (obj_sdr_record,
3176 "positive_going_threshold_hysteresis",
3177 &val) < 0)
3178 {
3179 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
3180 goto cleanup;
3181 }
3182 *positive_going_threshold_hysteresis = val;
3183 }
3184 if (negative_going_threshold_hysteresis)
3185 {
3186 if (FIID_OBJ_GET (obj_sdr_record,
3187 "negative_going_threshold_hysteresis",
3188 &val) < 0)
3189 {
3190 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
3191 goto cleanup;
3192 }
3193 *negative_going_threshold_hysteresis = val;
3194 }
3195 rv = 0;
3196 ctx->errnum = IPMI_SDR_ERR_SUCCESS;
3197 cleanup:
3198 fiid_obj_destroy (obj_sdr_record);
3199 return (rv);
3200 }
3201
3202 int
ipmi_sdr_parse_sensor_record_sharing(ipmi_sdr_ctx_t ctx,const void * sdr_record,unsigned int sdr_record_len,uint8_t * share_count,uint8_t * id_string_instance_modifier_type,uint8_t * id_string_instance_modifier_offset,uint8_t * entity_instance_sharing)3203 ipmi_sdr_parse_sensor_record_sharing (ipmi_sdr_ctx_t ctx,
3204 const void *sdr_record,
3205 unsigned int sdr_record_len,
3206 uint8_t *share_count,
3207 uint8_t *id_string_instance_modifier_type,
3208 uint8_t *id_string_instance_modifier_offset,
3209 uint8_t *entity_instance_sharing)
3210 {
3211 fiid_obj_t obj_sdr_record = NULL;
3212 uint32_t acceptable_record_types;
3213 uint64_t val;
3214 int rv = -1;
3215
3216 acceptable_record_types = IPMI_SDR_PARSE_RECORD_TYPE_COMPACT_SENSOR_RECORD;
3217 acceptable_record_types |= IPMI_SDR_PARSE_RECORD_TYPE_EVENT_ONLY_RECORD;
3218
3219 if (!(obj_sdr_record = _sdr_record_get_common (ctx,
3220 sdr_record,
3221 sdr_record_len,
3222 acceptable_record_types)))
3223 goto cleanup;
3224
3225 if (share_count)
3226 {
3227 if (FIID_OBJ_GET (obj_sdr_record,
3228 "share_count",
3229 &val) < 0)
3230 {
3231 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
3232 goto cleanup;
3233 }
3234 *share_count = val;
3235 }
3236
3237 if (id_string_instance_modifier_type)
3238 {
3239 if (FIID_OBJ_GET (obj_sdr_record,
3240 "id_string_instance_modifier_type",
3241 &val) < 0)
3242 {
3243 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
3244 goto cleanup;
3245 }
3246 *id_string_instance_modifier_type = val;
3247 }
3248
3249 if (id_string_instance_modifier_offset)
3250 {
3251 if (FIID_OBJ_GET (obj_sdr_record,
3252 "id_string_instance_modifier_offset",
3253 &val) < 0)
3254 {
3255 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
3256 goto cleanup;
3257 }
3258 *id_string_instance_modifier_offset = val;
3259 }
3260
3261 if (entity_instance_sharing)
3262 {
3263 if (FIID_OBJ_GET (obj_sdr_record,
3264 "entity_instance_sharing",
3265 &val) < 0)
3266 {
3267 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
3268 goto cleanup;
3269 }
3270 *entity_instance_sharing = val;
3271 }
3272
3273 rv = 0;
3274 ctx->errnum = IPMI_SDR_ERR_SUCCESS;
3275 cleanup:
3276 fiid_obj_destroy (obj_sdr_record);
3277 return (rv);
3278 }
3279
3280 int
ipmi_sdr_parse_container_entity(ipmi_sdr_ctx_t ctx,const void * sdr_record,unsigned int sdr_record_len,uint8_t * container_entity_id,uint8_t * container_entity_instance)3281 ipmi_sdr_parse_container_entity (ipmi_sdr_ctx_t ctx,
3282 const void *sdr_record,
3283 unsigned int sdr_record_len,
3284 uint8_t *container_entity_id,
3285 uint8_t *container_entity_instance)
3286 {
3287 fiid_obj_t obj_sdr_record = NULL;
3288 uint32_t acceptable_record_types;
3289 uint64_t val;
3290 int rv = -1;
3291
3292 acceptable_record_types = IPMI_SDR_PARSE_RECORD_TYPE_ENTITY_ASSOCIATION_RECORD;
3293 acceptable_record_types |= IPMI_SDR_PARSE_RECORD_TYPE_DEVICE_RELATIVE_ENTITY_ASSOCIATION_RECORD;
3294
3295 if (!(obj_sdr_record = _sdr_record_get_common (ctx,
3296 sdr_record,
3297 sdr_record_len,
3298 acceptable_record_types)))
3299 goto cleanup;
3300
3301 if (container_entity_id)
3302 {
3303 if (FIID_OBJ_GET (obj_sdr_record,
3304 "container_entity_id",
3305 &val) < 0)
3306 {
3307 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
3308 goto cleanup;
3309 }
3310 *container_entity_id = val;
3311 }
3312
3313 if (container_entity_instance)
3314 {
3315 if (FIID_OBJ_GET (obj_sdr_record,
3316 "container_entity_instance",
3317 &val) < 0)
3318 {
3319 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
3320 goto cleanup;
3321 }
3322 *container_entity_instance = val;
3323 }
3324
3325 rv = 0;
3326 ctx->errnum = IPMI_SDR_ERR_SUCCESS;
3327 cleanup:
3328 fiid_obj_destroy (obj_sdr_record);
3329 return (rv);
3330 }
3331
3332 int
ipmi_sdr_parse_device_id_string(ipmi_sdr_ctx_t ctx,const void * sdr_record,unsigned int sdr_record_len,char * device_id_string,unsigned int device_id_string_len)3333 ipmi_sdr_parse_device_id_string (ipmi_sdr_ctx_t ctx,
3334 const void *sdr_record,
3335 unsigned int sdr_record_len,
3336 char *device_id_string,
3337 unsigned int device_id_string_len)
3338 {
3339 fiid_obj_t obj_sdr_record = NULL;
3340 uint32_t acceptable_record_types;
3341 int len = 0;
3342 int rv = -1;
3343
3344 acceptable_record_types = IPMI_SDR_PARSE_RECORD_TYPE_GENERIC_DEVICE_LOCATOR_RECORD;
3345 acceptable_record_types |= IPMI_SDR_PARSE_RECORD_TYPE_FRU_DEVICE_LOCATOR_RECORD;
3346 acceptable_record_types |= IPMI_SDR_PARSE_RECORD_TYPE_MANAGEMENT_CONTROLLER_DEVICE_LOCATOR_RECORD;
3347
3348 if (!(obj_sdr_record = _sdr_record_get_common (ctx,
3349 sdr_record,
3350 sdr_record_len,
3351 acceptable_record_types)))
3352 goto cleanup;
3353
3354 if (device_id_string && device_id_string_len)
3355 {
3356 if ((len = fiid_obj_get_data (obj_sdr_record,
3357 "device_id_string",
3358 device_id_string,
3359 device_id_string_len)) < 0)
3360 {
3361 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
3362 goto cleanup;
3363 }
3364 }
3365
3366 rv = len;
3367 ctx->errnum = IPMI_SDR_ERR_SUCCESS;
3368 cleanup:
3369 fiid_obj_destroy (obj_sdr_record);
3370 return (rv);
3371 }
3372
3373 int
ipmi_sdr_parse_device_type(ipmi_sdr_ctx_t ctx,const void * sdr_record,unsigned int sdr_record_len,uint8_t * device_type,uint8_t * device_type_modifier)3374 ipmi_sdr_parse_device_type (ipmi_sdr_ctx_t ctx,
3375 const void *sdr_record,
3376 unsigned int sdr_record_len,
3377 uint8_t *device_type,
3378 uint8_t *device_type_modifier)
3379 {
3380 fiid_obj_t obj_sdr_record = NULL;
3381 uint32_t acceptable_record_types;
3382 uint64_t val;
3383 int rv = -1;
3384
3385 acceptable_record_types = IPMI_SDR_PARSE_RECORD_TYPE_GENERIC_DEVICE_LOCATOR_RECORD;
3386 acceptable_record_types |= IPMI_SDR_PARSE_RECORD_TYPE_FRU_DEVICE_LOCATOR_RECORD;
3387
3388 if (!(obj_sdr_record = _sdr_record_get_common (ctx,
3389 sdr_record,
3390 sdr_record_len,
3391 acceptable_record_types)))
3392 goto cleanup;
3393
3394 if (device_type)
3395 {
3396 if (FIID_OBJ_GET (obj_sdr_record,
3397 "device_type",
3398 &val) < 0)
3399 {
3400 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
3401 goto cleanup;
3402 }
3403 *device_type = val;
3404 }
3405 if (device_type_modifier)
3406 {
3407 if (FIID_OBJ_GET (obj_sdr_record,
3408 "device_type_modifier",
3409 &val) < 0)
3410 {
3411 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
3412 goto cleanup;
3413 }
3414 *device_type_modifier = val;
3415 }
3416
3417 rv = 0;
3418 ctx->errnum = IPMI_SDR_ERR_SUCCESS;
3419 cleanup:
3420 fiid_obj_destroy (obj_sdr_record);
3421 return (rv);
3422 }
3423
3424 int
ipmi_sdr_parse_generic_device_locator_parameters(ipmi_sdr_ctx_t ctx,const void * sdr_record,unsigned int sdr_record_len,uint8_t * device_access_address,uint8_t * channel_number,uint8_t * device_slave_address,uint8_t * private_bus_id,uint8_t * lun_for_master_write_read_command,uint8_t * address_span,uint8_t * oem)3425 ipmi_sdr_parse_generic_device_locator_parameters (ipmi_sdr_ctx_t ctx,
3426 const void *sdr_record,
3427 unsigned int sdr_record_len,
3428 uint8_t *device_access_address,
3429 uint8_t *channel_number,
3430 uint8_t *device_slave_address,
3431 uint8_t *private_bus_id,
3432 uint8_t *lun_for_master_write_read_command,
3433 uint8_t *address_span,
3434 uint8_t *oem)
3435 {
3436 fiid_obj_t obj_sdr_record = NULL;
3437 uint32_t acceptable_record_types;
3438 uint64_t val1, val2;
3439 uint64_t val;
3440 int rv = -1;
3441
3442 acceptable_record_types = IPMI_SDR_PARSE_RECORD_TYPE_GENERIC_DEVICE_LOCATOR_RECORD;
3443
3444 if (!(obj_sdr_record = _sdr_record_get_common (ctx,
3445 sdr_record,
3446 sdr_record_len,
3447 acceptable_record_types)))
3448 goto cleanup;
3449
3450 if (device_access_address)
3451 {
3452 if (FIID_OBJ_GET (obj_sdr_record,
3453 "device_access_address",
3454 &val) < 0)
3455 {
3456 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
3457 goto cleanup;
3458 }
3459 *device_access_address = val;
3460 }
3461 if (channel_number)
3462 {
3463 if (FIID_OBJ_GET (obj_sdr_record,
3464 "channel_number_ls",
3465 &val1) < 0)
3466 {
3467 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
3468 goto cleanup;
3469 }
3470 if (FIID_OBJ_GET (obj_sdr_record,
3471 "channel_number_ms",
3472 &val2) < 0)
3473 {
3474 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
3475 goto cleanup;
3476 }
3477 *channel_number = ((uint8_t)val1 << 3) | (uint8_t)val2;
3478 }
3479 if (device_slave_address)
3480 {
3481 if (FIID_OBJ_GET (obj_sdr_record,
3482 "device_slave_address",
3483 &val) < 0)
3484 {
3485 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
3486 goto cleanup;
3487 }
3488 *device_slave_address = val;
3489 }
3490 if (private_bus_id)
3491 {
3492 if (FIID_OBJ_GET (obj_sdr_record,
3493 "private_bus_id",
3494 &val) < 0)
3495 {
3496 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
3497 goto cleanup;
3498 }
3499 *private_bus_id = val;
3500 }
3501 if (lun_for_master_write_read_command)
3502 {
3503 if (FIID_OBJ_GET (obj_sdr_record,
3504 "lun_for_master_write_read_command",
3505 &val) < 0)
3506 {
3507 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
3508 goto cleanup;
3509 }
3510 *lun_for_master_write_read_command = val;
3511 }
3512 if (address_span)
3513 {
3514 if (FIID_OBJ_GET (obj_sdr_record,
3515 "address_span",
3516 &val) < 0)
3517 {
3518 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
3519 goto cleanup;
3520 }
3521 *address_span = val;
3522 }
3523 if (oem)
3524 {
3525 if (FIID_OBJ_GET (obj_sdr_record,
3526 "oem",
3527 &val) < 0)
3528 {
3529 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
3530 goto cleanup;
3531 }
3532 *oem = val;
3533 }
3534
3535 rv = 0;
3536 ctx->errnum = IPMI_SDR_ERR_SUCCESS;
3537 cleanup:
3538 fiid_obj_destroy (obj_sdr_record);
3539 return (rv);
3540 }
3541
3542 int
ipmi_sdr_parse_fru_device_locator_parameters(ipmi_sdr_ctx_t ctx,const void * sdr_record,unsigned int sdr_record_len,uint8_t * device_access_address,uint8_t * logical_fru_device_device_slave_address,uint8_t * private_bus_id,uint8_t * lun_for_master_write_read_fru_command,uint8_t * logical_physical_fru_device,uint8_t * channel_number)3543 ipmi_sdr_parse_fru_device_locator_parameters (ipmi_sdr_ctx_t ctx,
3544 const void *sdr_record,
3545 unsigned int sdr_record_len,
3546 uint8_t *device_access_address,
3547 uint8_t *logical_fru_device_device_slave_address,
3548 uint8_t *private_bus_id,
3549 uint8_t *lun_for_master_write_read_fru_command,
3550 uint8_t *logical_physical_fru_device,
3551 uint8_t *channel_number)
3552 {
3553 fiid_obj_t obj_sdr_record = NULL;
3554 uint32_t acceptable_record_types;
3555 uint64_t val;
3556 int rv = -1;
3557
3558 acceptable_record_types = IPMI_SDR_PARSE_RECORD_TYPE_FRU_DEVICE_LOCATOR_RECORD;
3559
3560 if (!(obj_sdr_record = _sdr_record_get_common (ctx,
3561 sdr_record,
3562 sdr_record_len,
3563 acceptable_record_types)))
3564 goto cleanup;
3565
3566 if (device_access_address)
3567 {
3568 if (FIID_OBJ_GET (obj_sdr_record,
3569 "device_access_address",
3570 &val) < 0)
3571 {
3572 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
3573 goto cleanup;
3574 }
3575 *device_access_address = val;
3576 }
3577 if (logical_fru_device_device_slave_address)
3578 {
3579 if (FIID_OBJ_GET (obj_sdr_record,
3580 "logical_fru_device_device_slave_address",
3581 &val) < 0)
3582 {
3583 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
3584 goto cleanup;
3585 }
3586 *logical_fru_device_device_slave_address = val;
3587 }
3588 if (private_bus_id)
3589 {
3590 if (FIID_OBJ_GET (obj_sdr_record,
3591 "private_bus_id",
3592 &val) < 0)
3593 {
3594 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
3595 goto cleanup;
3596 }
3597 *private_bus_id = val;
3598 }
3599 if (lun_for_master_write_read_fru_command)
3600 {
3601 if (FIID_OBJ_GET (obj_sdr_record,
3602 "lun_for_master_write_read_fru_command",
3603 &val) < 0)
3604 {
3605 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
3606 goto cleanup;
3607 }
3608 *lun_for_master_write_read_fru_command = val;
3609 }
3610 if (logical_physical_fru_device)
3611 {
3612 if (FIID_OBJ_GET (obj_sdr_record,
3613 "logical_physical_fru_device",
3614 &val) < 0)
3615 {
3616 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
3617 goto cleanup;
3618 }
3619 *logical_physical_fru_device = val;
3620 }
3621 if (channel_number)
3622 {
3623 if (FIID_OBJ_GET (obj_sdr_record,
3624 "channel_number",
3625 &val) < 0)
3626 {
3627 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
3628 goto cleanup;
3629 }
3630 *channel_number = val;
3631 }
3632
3633 rv = 0;
3634 ctx->errnum = IPMI_SDR_ERR_SUCCESS;
3635 cleanup:
3636 fiid_obj_destroy (obj_sdr_record);
3637 return (rv);
3638 }
3639
3640 int
ipmi_sdr_parse_fru_entity_id_and_instance(ipmi_sdr_ctx_t ctx,const void * sdr_record,unsigned int sdr_record_len,uint8_t * fru_entity_id,uint8_t * fru_entity_instance)3641 ipmi_sdr_parse_fru_entity_id_and_instance (ipmi_sdr_ctx_t ctx,
3642 const void *sdr_record,
3643 unsigned int sdr_record_len,
3644 uint8_t *fru_entity_id,
3645 uint8_t *fru_entity_instance)
3646 {
3647 fiid_obj_t obj_sdr_record = NULL;
3648 uint32_t acceptable_record_types;
3649 uint64_t val;
3650 int rv = -1;
3651
3652 acceptable_record_types = IPMI_SDR_PARSE_RECORD_TYPE_FRU_DEVICE_LOCATOR_RECORD;
3653
3654 if (!(obj_sdr_record = _sdr_record_get_common (ctx,
3655 sdr_record,
3656 sdr_record_len,
3657 acceptable_record_types)))
3658 goto cleanup;
3659
3660 if (fru_entity_id)
3661 {
3662 if (FIID_OBJ_GET (obj_sdr_record,
3663 "fru_entity_id",
3664 &val) < 0)
3665 {
3666 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
3667 goto cleanup;
3668 }
3669 *fru_entity_id = val;
3670 }
3671 if (fru_entity_instance)
3672 {
3673 if (FIID_OBJ_GET (obj_sdr_record,
3674 "fru_entity_instance",
3675 &val) < 0)
3676 {
3677 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
3678 goto cleanup;
3679 }
3680 *fru_entity_instance = val;
3681 }
3682
3683 rv = 0;
3684 ctx->errnum = IPMI_SDR_ERR_SUCCESS;
3685 cleanup:
3686 fiid_obj_destroy (obj_sdr_record);
3687 return (rv);
3688 }
3689
3690 int
ipmi_sdr_parse_management_controller_device_locator_parameters(ipmi_sdr_ctx_t ctx,const void * sdr_record,unsigned int sdr_record_len,uint8_t * device_slave_address,uint8_t * channel_number,uint8_t * global_initialization_event_message_generation,uint8_t * global_initialization_log_initialization_agent_errors,uint8_t * global_initialization_controller_logs_initialization_agent_errors,uint8_t * power_state_notification_controller,uint8_t * power_state_notification_acpi_device_power_state_notification,uint8_t * power_state_notification_acpi_system_power_state_notification,uint8_t * device_capabilities_sensor_device,uint8_t * device_capabilities_sdr_repository_device,uint8_t * device_capabilities_sel_device,uint8_t * device_capabilities_fru_inventory_device,uint8_t * device_capabilities_ipmb_event_receiver,uint8_t * device_capabilities_ipmb_event_generator,uint8_t * device_capabilities_bridge,uint8_t * device_capabilities_chassis_device)3691 ipmi_sdr_parse_management_controller_device_locator_parameters (ipmi_sdr_ctx_t ctx,
3692 const void *sdr_record,
3693 unsigned int sdr_record_len,
3694 uint8_t *device_slave_address,
3695 uint8_t *channel_number,
3696 uint8_t *global_initialization_event_message_generation,
3697 uint8_t *global_initialization_log_initialization_agent_errors,
3698 uint8_t *global_initialization_controller_logs_initialization_agent_errors,
3699 uint8_t *power_state_notification_controller,
3700 uint8_t *power_state_notification_acpi_device_power_state_notification,
3701 uint8_t *power_state_notification_acpi_system_power_state_notification,
3702 uint8_t *device_capabilities_sensor_device,
3703 uint8_t *device_capabilities_sdr_repository_device,
3704 uint8_t *device_capabilities_sel_device,
3705 uint8_t *device_capabilities_fru_inventory_device,
3706 uint8_t *device_capabilities_ipmb_event_receiver,
3707 uint8_t *device_capabilities_ipmb_event_generator,
3708 uint8_t *device_capabilities_bridge,
3709 uint8_t *device_capabilities_chassis_device)
3710 {
3711 fiid_obj_t obj_sdr_record = NULL;
3712 uint32_t acceptable_record_types;
3713 uint64_t val;
3714 int rv = -1;
3715
3716 acceptable_record_types = IPMI_SDR_PARSE_RECORD_TYPE_MANAGEMENT_CONTROLLER_DEVICE_LOCATOR_RECORD;
3717
3718 if (!(obj_sdr_record = _sdr_record_get_common (ctx,
3719 sdr_record,
3720 sdr_record_len,
3721 acceptable_record_types)))
3722 goto cleanup;
3723
3724 if (device_slave_address)
3725 {
3726 if (FIID_OBJ_GET (obj_sdr_record,
3727 "device_slave_address",
3728 &val) < 0)
3729 {
3730 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
3731 goto cleanup;
3732 }
3733 *device_slave_address = val;
3734 }
3735 if (channel_number)
3736 {
3737 if (FIID_OBJ_GET (obj_sdr_record,
3738 "channel_number",
3739 &val) < 0)
3740 {
3741 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
3742 goto cleanup;
3743 }
3744 *channel_number = val;
3745 }
3746 if (global_initialization_event_message_generation)
3747 {
3748 if (FIID_OBJ_GET (obj_sdr_record,
3749 "global_initialization.event_message_generation",
3750 &val) < 0)
3751 {
3752 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
3753 goto cleanup;
3754 }
3755 *global_initialization_event_message_generation = val;
3756 }
3757 if (global_initialization_log_initialization_agent_errors)
3758 {
3759 if (FIID_OBJ_GET (obj_sdr_record,
3760 "global_initialization.log_initialization_agent_errors",
3761 &val) < 0)
3762 {
3763 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
3764 goto cleanup;
3765 }
3766 *global_initialization_log_initialization_agent_errors = val;
3767 }
3768 if (global_initialization_controller_logs_initialization_agent_errors)
3769 {
3770 if (FIID_OBJ_GET (obj_sdr_record,
3771 "global_initialization.controller_logs_initialization_agent_errors",
3772 &val) < 0)
3773 {
3774 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
3775 goto cleanup;
3776 }
3777 *global_initialization_controller_logs_initialization_agent_errors = val;
3778 }
3779 if (power_state_notification_controller)
3780 {
3781 if (FIID_OBJ_GET (obj_sdr_record,
3782 "power_state_notification.controller",
3783 &val) < 0)
3784 {
3785 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
3786 goto cleanup;
3787 }
3788 *power_state_notification_controller = val;
3789 }
3790 if (power_state_notification_acpi_device_power_state_notification)
3791 {
3792 if (FIID_OBJ_GET (obj_sdr_record,
3793 "power_state_notification.acpi_device_power_state_notification",
3794 &val) < 0)
3795 {
3796 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
3797 goto cleanup;
3798 }
3799 *power_state_notification_acpi_device_power_state_notification = val;
3800 }
3801 if (power_state_notification_acpi_system_power_state_notification)
3802 {
3803 if (FIID_OBJ_GET (obj_sdr_record,
3804 "power_state_notification.acpi_system_power_state_notification",
3805 &val) < 0)
3806 {
3807 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
3808 goto cleanup;
3809 }
3810 *power_state_notification_acpi_system_power_state_notification = val;
3811 }
3812 if (device_capabilities_sensor_device)
3813 {
3814 if (FIID_OBJ_GET (obj_sdr_record,
3815 "device_capabilities.sensor_device",
3816 &val) < 0)
3817 {
3818 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
3819 goto cleanup;
3820 }
3821 *device_capabilities_sensor_device = val;
3822 }
3823 if (device_capabilities_sdr_repository_device)
3824 {
3825 if (FIID_OBJ_GET (obj_sdr_record,
3826 "device_capabilities.sdr_repository_device",
3827 &val) < 0)
3828 {
3829 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
3830 goto cleanup;
3831 }
3832 *device_capabilities_sdr_repository_device = val;
3833 }
3834 if (device_capabilities_sel_device)
3835 {
3836 if (FIID_OBJ_GET (obj_sdr_record,
3837 "device_capabilities.sel_device",
3838 &val) < 0)
3839 {
3840 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
3841 goto cleanup;
3842 }
3843 *device_capabilities_sel_device = val;
3844 }
3845 if (device_capabilities_fru_inventory_device)
3846 {
3847 if (FIID_OBJ_GET (obj_sdr_record,
3848 "device_capabilities.fru_inventory_device",
3849 &val) < 0)
3850 {
3851 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
3852 goto cleanup;
3853 }
3854 *device_capabilities_fru_inventory_device = val;
3855 }
3856 if (device_capabilities_ipmb_event_receiver)
3857 {
3858 if (FIID_OBJ_GET (obj_sdr_record,
3859 "device_capabilities.ipmb_event_receiver",
3860 &val) < 0)
3861 {
3862 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
3863 goto cleanup;
3864 }
3865 *device_capabilities_ipmb_event_receiver = val;
3866 }
3867 if (device_capabilities_ipmb_event_generator)
3868 {
3869 if (FIID_OBJ_GET (obj_sdr_record,
3870 "device_capabilities.ipmb_event_generator",
3871 &val) < 0)
3872 {
3873 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
3874 goto cleanup;
3875 }
3876 *device_capabilities_ipmb_event_generator = val;
3877 }
3878 if (device_capabilities_bridge)
3879 {
3880 if (FIID_OBJ_GET (obj_sdr_record,
3881 "device_capabilities.bridge",
3882 &val) < 0)
3883 {
3884 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
3885 goto cleanup;
3886 }
3887 *device_capabilities_bridge = val;
3888 }
3889 if (device_capabilities_chassis_device)
3890 {
3891 if (FIID_OBJ_GET (obj_sdr_record,
3892 "device_capabilities.chassis_device",
3893 &val) < 0)
3894 {
3895 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
3896 goto cleanup;
3897 }
3898 *device_capabilities_chassis_device = val;
3899 }
3900
3901 rv = 0;
3902 ctx->errnum = IPMI_SDR_ERR_SUCCESS;
3903 cleanup:
3904 fiid_obj_destroy (obj_sdr_record);
3905 return (rv);
3906 }
3907
3908 int
ipmi_sdr_parse_manufacturer_id(ipmi_sdr_ctx_t ctx,const void * sdr_record,unsigned int sdr_record_len,uint32_t * manufacturer_id)3909 ipmi_sdr_parse_manufacturer_id (ipmi_sdr_ctx_t ctx,
3910 const void *sdr_record,
3911 unsigned int sdr_record_len,
3912 uint32_t *manufacturer_id)
3913 {
3914 fiid_obj_t obj_sdr_record = NULL;
3915 uint32_t acceptable_record_types;
3916 uint64_t val;
3917 int rv = -1;
3918
3919 acceptable_record_types = IPMI_SDR_PARSE_RECORD_TYPE_MANAGEMENT_CONTROLLER_CONFIRMATION_RECORD;
3920 acceptable_record_types |= IPMI_SDR_PARSE_RECORD_TYPE_OEM_RECORD;
3921
3922 if (!(obj_sdr_record = _sdr_record_get_common (ctx,
3923 sdr_record,
3924 sdr_record_len,
3925 acceptable_record_types)))
3926 goto cleanup;
3927
3928 if (manufacturer_id)
3929 {
3930 if (FIID_OBJ_GET (obj_sdr_record,
3931 "manufacturer_id",
3932 &val) < 0)
3933 {
3934 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
3935 goto cleanup;
3936 }
3937 *manufacturer_id = val;
3938 }
3939
3940 rv = 0;
3941 ctx->errnum = IPMI_SDR_ERR_SUCCESS;
3942 cleanup:
3943 fiid_obj_destroy (obj_sdr_record);
3944 return (rv);
3945 }
3946
3947 int
ipmi_sdr_parse_product_id(ipmi_sdr_ctx_t ctx,const void * sdr_record,unsigned int sdr_record_len,uint16_t * product_id)3948 ipmi_sdr_parse_product_id (ipmi_sdr_ctx_t ctx,
3949 const void *sdr_record,
3950 unsigned int sdr_record_len,
3951 uint16_t *product_id)
3952 {
3953 fiid_obj_t obj_sdr_record = NULL;
3954 uint32_t acceptable_record_types;
3955 uint64_t val;
3956 int rv = -1;
3957
3958 acceptable_record_types = IPMI_SDR_PARSE_RECORD_TYPE_MANAGEMENT_CONTROLLER_CONFIRMATION_RECORD;
3959
3960 if (!(obj_sdr_record = _sdr_record_get_common (ctx,
3961 sdr_record,
3962 sdr_record_len,
3963 acceptable_record_types)))
3964 goto cleanup;
3965
3966 if (product_id)
3967 {
3968 if (FIID_OBJ_GET (obj_sdr_record,
3969 "product_id",
3970 &val) < 0)
3971 {
3972 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
3973 goto cleanup;
3974 }
3975 *product_id = val;
3976 }
3977
3978 rv = 0;
3979 ctx->errnum = IPMI_SDR_ERR_SUCCESS;
3980 cleanup:
3981 fiid_obj_destroy (obj_sdr_record);
3982 return (rv);
3983 }
3984
3985 int
ipmi_sdr_parse_oem_data(ipmi_sdr_ctx_t ctx,const void * sdr_record,unsigned int sdr_record_len,void * oem_data,unsigned int oem_data_len)3986 ipmi_sdr_parse_oem_data (ipmi_sdr_ctx_t ctx,
3987 const void *sdr_record,
3988 unsigned int sdr_record_len,
3989 void *oem_data,
3990 unsigned int oem_data_len)
3991 {
3992 fiid_obj_t obj_sdr_record = NULL;
3993 uint32_t acceptable_record_types;
3994 int len = 0;
3995 int rv = -1;
3996
3997 acceptable_record_types = IPMI_SDR_PARSE_RECORD_TYPE_OEM_RECORD;
3998
3999 if (!(obj_sdr_record = _sdr_record_get_common (ctx,
4000 sdr_record,
4001 sdr_record_len,
4002 acceptable_record_types)))
4003 goto cleanup;
4004
4005 if (oem_data && oem_data_len)
4006 {
4007 if ((len = fiid_obj_get_data (obj_sdr_record,
4008 "oem_data",
4009 oem_data,
4010 oem_data_len)) < 0)
4011 {
4012 SDR_FIID_OBJECT_ERROR_TO_SDR_ERRNUM (ctx, obj_sdr_record);
4013 goto cleanup;
4014 }
4015 }
4016
4017 rv = len;
4018 ctx->errnum = IPMI_SDR_ERR_SUCCESS;
4019 cleanup:
4020 fiid_obj_destroy (obj_sdr_record);
4021 return (rv);
4022 }
4023