1 /*
2 * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * Redistribution of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * Redistribution in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * Neither the name of Sun Microsystems, Inc. or the names of
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * This software is provided "AS IS," without a warranty of any kind.
20 * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
21 * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
22 * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED.
23 * SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE
24 * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
25 * OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL
26 * SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA,
27 * OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR
28 * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF
29 * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
30 * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
31 */
32
33 #include <string.h>
34 #include <math.h>
35
36 #include <ipmitool/ipmi.h>
37 #include <ipmitool/helper.h>
38 #include <ipmitool/log.h>
39 #include <ipmitool/ipmi_intf.h>
40 #include <ipmitool/ipmi_sdr.h>
41 #include <ipmitool/ipmi_sel.h>
42 #include <ipmitool/ipmi_sensor.h>
43
44 extern int verbose;
45 void print_sensor_get_usage();
46 void print_sensor_thresh_usage();
47
48 // Macro's for Reading the current sensor Data.
49 #define SCANNING_DISABLED 0x40
50 #define READING_UNAVAILABLE 0x20
51 #define INVALID_THRESHOLD "Invalid Threshold data values. Cannot Set Threshold Data."
52 // static
53 int
ipmi_sensor_get_sensor_reading_factors(struct ipmi_intf * intf,struct sdr_record_full_sensor * sensor,uint8_t reading)54 ipmi_sensor_get_sensor_reading_factors(
55 struct ipmi_intf * intf,
56 struct sdr_record_full_sensor * sensor,
57 uint8_t reading)
58 {
59 struct ipmi_rq req;
60 struct ipmi_rs * rsp;
61 uint8_t req_data[2];
62
63 char id[17];
64
65 if (intf == NULL || sensor == NULL)
66 return -1;
67
68 memset(id, 0, sizeof(id));
69 memcpy(id, sensor->id_string, 16);
70
71 req_data[0] = sensor->cmn.keys.sensor_num;
72 req_data[1] = reading;
73
74 memset(&req, 0, sizeof(req));
75 req.msg.netfn = IPMI_NETFN_SE;
76 req.msg.lun = sensor->cmn.keys.lun;
77 req.msg.cmd = GET_SENSOR_FACTORS;
78 req.msg.data = req_data;
79 req.msg.data_len = sizeof(req_data);
80
81 rsp = intf->sendrecv(intf, &req);
82
83 if (rsp == NULL) {
84 lprintf(LOG_ERR, "Error updating reading factor for sensor %s (#%02x)",
85 id, sensor->cmn.keys.sensor_num);
86 return -1;
87 } else if (rsp->ccode) {
88 return -1;
89 } else {
90 /* Update SDR copy with updated Reading Factors for this reading */
91 /* Note:
92 * The Format of the returned data is exactly as in the SDR definition (Little Endian Format),
93 * therefore we can use raw copy operation here.
94 * Note: rsp->data[0] would point to the next valid entry in the sampling table
95 */
96 // BUGBUG: uses 'hardcoded' length information from SDR Definition
97 memcpy(&sensor->mtol, &rsp->data[1], sizeof(sensor->mtol));
98 memcpy(&sensor->bacc, &rsp->data[3], sizeof(sensor->bacc));
99 return 0;
100 }
101
102 }
103
104 static
105 struct ipmi_rs *
ipmi_sensor_set_sensor_thresholds(struct ipmi_intf * intf,uint8_t sensor,uint8_t threshold,uint8_t setting,uint8_t target,uint8_t lun,uint8_t channel)106 ipmi_sensor_set_sensor_thresholds(struct ipmi_intf *intf,
107 uint8_t sensor,
108 uint8_t threshold, uint8_t setting,
109 uint8_t target, uint8_t lun, uint8_t channel)
110 {
111 struct ipmi_rq req;
112 static struct sensor_set_thresh_rq set_thresh_rq;
113 struct ipmi_rs *rsp;
114 uint8_t bridged_request = 0;
115 uint32_t save_addr;
116 uint32_t save_channel;
117
118 memset(&set_thresh_rq, 0, sizeof (set_thresh_rq));
119 set_thresh_rq.sensor_num = sensor;
120 set_thresh_rq.set_mask = threshold;
121 if (threshold == UPPER_NON_RECOV_SPECIFIED)
122 set_thresh_rq.upper_non_recov = setting;
123 else if (threshold == UPPER_CRIT_SPECIFIED)
124 set_thresh_rq.upper_crit = setting;
125 else if (threshold == UPPER_NON_CRIT_SPECIFIED)
126 set_thresh_rq.upper_non_crit = setting;
127 else if (threshold == LOWER_NON_CRIT_SPECIFIED)
128 set_thresh_rq.lower_non_crit = setting;
129 else if (threshold == LOWER_CRIT_SPECIFIED)
130 set_thresh_rq.lower_crit = setting;
131 else if (threshold == LOWER_NON_RECOV_SPECIFIED)
132 set_thresh_rq.lower_non_recov = setting;
133 else
134 return NULL;
135
136 if (BRIDGE_TO_SENSOR(intf, target, channel)) {
137 bridged_request = 1;
138 save_addr = intf->target_addr;
139 intf->target_addr = target;
140 save_channel = intf->target_channel;
141 intf->target_channel = channel;
142 }
143 memset(&req, 0, sizeof (req));
144 req.msg.netfn = IPMI_NETFN_SE;
145 req.msg.lun = lun;
146 req.msg.cmd = SET_SENSOR_THRESHOLDS;
147 req.msg.data = (uint8_t *) & set_thresh_rq;
148 req.msg.data_len = sizeof (set_thresh_rq);
149
150 rsp = intf->sendrecv(intf, &req);
151 if (bridged_request) {
152 intf->target_addr = save_addr;
153 intf->target_channel = save_channel;
154 }
155 return rsp;
156 }
157
158 static int
ipmi_sensor_print_fc_discrete(struct ipmi_intf * intf,struct sdr_record_common_sensor * sensor,uint8_t sdr_record_type)159 ipmi_sensor_print_fc_discrete(struct ipmi_intf *intf,
160 struct sdr_record_common_sensor *sensor,
161 uint8_t sdr_record_type)
162 {
163 struct sensor_reading *sr;
164
165 sr = ipmi_sdr_read_sensor_value(intf, sensor, sdr_record_type, 3);
166
167 if (sr == NULL) {
168 return -1;
169 }
170
171 if (csv_output) {
172 /* NOT IMPLEMENTED */
173 } else {
174 if (verbose == 0) {
175 /* output format
176 * id value units status thresholds....
177 */
178 printf("%-16s ", sr->s_id);
179 if (sr->s_reading_valid) {
180 if (sr->s_has_analog_value) {
181 /* don't show discrete component */
182 printf("| %-10s | %-10s | %-6s",
183 sr->s_a_str, sr->s_a_units, "ok");
184 } else {
185 printf("| 0x%-8x | %-10s | 0x%02x%02x",
186 sr->s_reading, "discrete",
187 sr->s_data2, sr->s_data3);
188 }
189 } else {
190 printf("| %-10s | %-10s | %-6s",
191 "na", "discrete", "na");
192 }
193 printf("| %-10s| %-10s| %-10s| %-10s| %-10s| %-10s",
194 "na", "na", "na", "na", "na", "na");
195
196 printf("\n");
197 } else {
198 printf("Sensor ID : %s (0x%x)\n",
199 sr->s_id, sensor->keys.sensor_num);
200 printf(" Entity ID : %d.%d\n",
201 sensor->entity.id, sensor->entity.instance);
202 printf(" Sensor Type (Discrete): %s\n",
203 ipmi_sdr_get_sensor_type_desc(sensor->sensor.
204 type));
205 if( sr->s_reading_valid )
206 {
207 if (sr->s_has_analog_value) {
208 printf(" Sensor Reading : %s %s\n", sr->s_a_str, sr->s_a_units);
209 }
210 ipmi_sdr_print_discrete_state("States Asserted",
211 sensor->sensor.type,
212 sensor->event_type,
213 sr->s_data2,
214 sr->s_data3);
215 printf("\n");
216 } else {
217 printf(" Unable to read sensor: Device Not Present\n\n");
218 }
219 }
220 }
221
222 return (sr->s_reading_valid ? 0 : -1 );
223 }
224
225 static void
print_thresh_setting(struct sdr_record_full_sensor * full,uint8_t thresh_is_avail,uint8_t setting,const char * field_sep,const char * analog_fmt,const char * discrete_fmt,const char * na_fmt)226 print_thresh_setting(struct sdr_record_full_sensor *full,
227 uint8_t thresh_is_avail, uint8_t setting,
228 const char *field_sep,
229 const char *analog_fmt,
230 const char *discrete_fmt,
231 const char *na_fmt)
232 {
233 printf("%s", field_sep);
234 if (!thresh_is_avail) {
235 printf(na_fmt, "na");
236 return;
237 }
238 if (full && !UNITS_ARE_DISCRETE(&full->cmn)) {
239 printf(analog_fmt, sdr_convert_sensor_reading (full, setting));
240 } else {
241 printf(discrete_fmt, setting);
242 }
243 }
244
245 static int
ipmi_sensor_print_fc_threshold(struct ipmi_intf * intf,struct sdr_record_common_sensor * sensor,uint8_t sdr_record_type)246 ipmi_sensor_print_fc_threshold(struct ipmi_intf *intf,
247 struct sdr_record_common_sensor *sensor,
248 uint8_t sdr_record_type)
249 {
250 int thresh_available = 1;
251 struct ipmi_rs *rsp;
252 struct sensor_reading *sr;
253
254 sr = ipmi_sdr_read_sensor_value(intf, sensor, sdr_record_type, 3);
255
256 if (sr == NULL) {
257 return -1;
258 }
259
260 const char *thresh_status = ipmi_sdr_get_thresh_status(sr, "ns");
261
262 /*
263 * Get sensor thresholds
264 */
265 rsp = ipmi_sdr_get_sensor_thresholds(intf,
266 sensor->keys.sensor_num, sensor->keys.owner_id,
267 sensor->keys.lun, sensor->keys.channel);
268
269 if ((rsp == NULL) || (rsp->ccode > 0) || (rsp->data_len == 0))
270 thresh_available = 0;
271
272 if (csv_output) {
273 /* NOT IMPLEMENTED */
274 } else {
275 if (verbose == 0) {
276 /* output format
277 * id value units status thresholds....
278 */
279 printf("%-16s ", sr->s_id);
280 if (sr->s_reading_valid) {
281 if (sr->s_has_analog_value)
282 printf("| %-10.3f | %-10s | %-6s",
283 sr->s_a_val, sr->s_a_units, thresh_status);
284 else
285 printf("| 0x%-8x | %-10s | %-6s",
286 sr->s_reading, sr->s_a_units, thresh_status);
287 } else {
288 printf("| %-10s | %-10s | %-6s",
289 "na", sr->s_a_units, "na");
290 }
291 if (thresh_available && sr->full) {
292 #define PTS(bit, dataidx) { \
293 print_thresh_setting(sr->full, rsp->data[0] & (bit), \
294 rsp->data[(dataidx)], "| ", "%-10.3f", "0x-8x", "%-10s"); \
295 }
296 PTS(LOWER_NON_RECOV_SPECIFIED, 3);
297 PTS(LOWER_CRIT_SPECIFIED, 2);
298 PTS(LOWER_NON_CRIT_SPECIFIED, 1);
299 PTS(UPPER_NON_CRIT_SPECIFIED, 4);
300 PTS(UPPER_CRIT_SPECIFIED, 5);
301 PTS(UPPER_NON_RECOV_SPECIFIED, 6);
302 #undef PTS
303 } else {
304 printf
305 ("| %-10s| %-10s| %-10s| %-10s| %-10s| %-10s",
306 "na", "na", "na", "na", "na", "na");
307 }
308
309 printf("\n");
310 } else {
311 printf("Sensor ID : %s (0x%x)\n",
312 sr->s_id, sensor->keys.sensor_num);
313
314 printf(" Entity ID : %d.%d\n",
315 sensor->entity.id, sensor->entity.instance);
316
317 printf(" Sensor Type (Threshold) : %s\n",
318 ipmi_sdr_get_sensor_type_desc(sensor->sensor.
319 type));
320
321 printf(" Sensor Reading : ");
322 if (sr->s_reading_valid) {
323 if (sr->full) {
324 uint16_t raw_tol = __TO_TOL(sr->full->mtol);
325 if (sr->s_has_analog_value) {
326 double tol =
327 sdr_convert_sensor_tolerance(sr->full,
328 raw_tol);
329 printf("%.*f (+/- %.*f) %s\n",
330 (sr->s_a_val == (int)
331 sr->s_a_val) ? 0 : 3,
332 sr->s_a_val,
333 (tol == (int) tol) ? 0 : 3, tol,
334 sr->s_a_units);
335 } else {
336 printf("0x%x (+/- 0x%x) %s\n",
337 sr->s_reading,
338 raw_tol,
339 sr->s_a_units);
340 }
341 } else {
342 printf("0x%x %s\n", sr->s_reading,
343 sr->s_a_units);
344 }
345 printf(" Status : %s\n", thresh_status);
346
347 if (thresh_available) {
348 if (sr->full) {
349 #define PTS(bit, dataidx, str) { \
350 print_thresh_setting(sr->full, rsp->data[0] & (bit), \
351 rsp->data[(dataidx)], \
352 (str), "%.3f\n", "0x%x\n", "%s\n"); \
353 }
354
355 PTS(LOWER_NON_RECOV_SPECIFIED, 3, " Lower Non-Recoverable : ");
356 PTS(LOWER_CRIT_SPECIFIED, 2, " Lower Critical : ");
357 PTS(LOWER_NON_CRIT_SPECIFIED, 1, " Lower Non-Critical : ");
358 PTS(UPPER_NON_CRIT_SPECIFIED, 4, " Upper Non-Critical : ");
359 PTS(UPPER_CRIT_SPECIFIED, 5, " Upper Critical : ");
360 PTS(UPPER_NON_RECOV_SPECIFIED, 6, " Upper Non-Recoverable : ");
361 #undef PTS
362
363 }
364 ipmi_sdr_print_sensor_hysteresis(sensor, sr->full,
365 sr->full ? sr->full->threshold.hysteresis.positive :
366 sr->compact->threshold.hysteresis.positive,
367 "Positive Hysteresis");
368
369 ipmi_sdr_print_sensor_hysteresis(sensor, sr->full,
370 sr->full ? sr->full->threshold.hysteresis.negative :
371 sr->compact->threshold.hysteresis.negative,
372 "Negative Hysteresis");
373 } else {
374 printf(" Sensor Threshold Settings not available\n");
375 }
376 } else {
377 printf(" Unable to read sensor: Device Not Present\n\n");
378 }
379
380 ipmi_sdr_print_sensor_event_status(intf,
381 sensor->keys.
382 sensor_num,
383 sensor->sensor.type,
384 sensor->event_type,
385 ANALOG_SENSOR,
386 sensor->keys.owner_id,
387 sensor->keys.lun,
388 sensor->keys.channel);
389 ipmi_sdr_print_sensor_event_enable(intf,
390 sensor->keys.
391 sensor_num,
392 sensor->sensor.type,
393 sensor->event_type,
394 ANALOG_SENSOR,
395 sensor->keys.owner_id,
396 sensor->keys.lun,
397 sensor->keys.channel);
398
399 printf("\n");
400 }
401 }
402
403 return (sr->s_reading_valid ? 0 : -1 );
404 }
405
406 int
ipmi_sensor_print_fc(struct ipmi_intf * intf,struct sdr_record_common_sensor * sensor,uint8_t sdr_record_type)407 ipmi_sensor_print_fc(struct ipmi_intf *intf,
408 struct sdr_record_common_sensor *sensor,
409 uint8_t sdr_record_type)
410 {
411 if (IS_THRESHOLD_SENSOR(sensor))
412 return ipmi_sensor_print_fc_threshold(intf, sensor, sdr_record_type);
413 else
414 return ipmi_sensor_print_fc_discrete(intf, sensor, sdr_record_type);
415 }
416
417 static int
ipmi_sensor_list(struct ipmi_intf * intf)418 ipmi_sensor_list(struct ipmi_intf *intf)
419 {
420 struct sdr_get_rs *header;
421 struct ipmi_sdr_iterator *itr;
422 int rc = 0;
423
424 lprintf(LOG_DEBUG, "Querying SDR for sensor list");
425
426 itr = ipmi_sdr_start(intf, 0);
427 if (itr == NULL) {
428 lprintf(LOG_ERR, "Unable to open SDR for reading");
429 return -1;
430 }
431
432 while ((header = ipmi_sdr_get_next_header(intf, itr)) != NULL) {
433 uint8_t *rec;
434
435 rec = ipmi_sdr_get_record(intf, header, itr);
436 if (rec == NULL) {
437 lprintf(LOG_DEBUG, "rec == NULL");
438 continue;
439 }
440
441 switch (header->type) {
442 case SDR_RECORD_TYPE_FULL_SENSOR:
443 case SDR_RECORD_TYPE_COMPACT_SENSOR:
444 ipmi_sensor_print_fc(intf,
445 (struct
446 sdr_record_common_sensor *)
447 rec,
448 header->type);
449 break;
450 }
451 free(rec);
452 rec = NULL;
453
454 /* fix for CR6604909: */
455 /* mask failure of individual reads in sensor list command */
456 /* rc = (r == 0) ? rc : r; */
457 }
458
459 ipmi_sdr_end(intf, itr);
460
461 return rc;
462 }
463
464 static const struct valstr threshold_vals[] = {
465 {UPPER_NON_RECOV_SPECIFIED, "Upper Non-Recoverable"},
466 {UPPER_CRIT_SPECIFIED, "Upper Critical"},
467 {UPPER_NON_CRIT_SPECIFIED, "Upper Non-Critical"},
468 {LOWER_NON_RECOV_SPECIFIED, "Lower Non-Recoverable"},
469 {LOWER_CRIT_SPECIFIED, "Lower Critical"},
470 {LOWER_NON_CRIT_SPECIFIED, "Lower Non-Critical"},
471 {0x00, NULL},
472 };
473
474 static int
__ipmi_sensor_set_threshold(struct ipmi_intf * intf,uint8_t num,uint8_t mask,uint8_t setting,uint8_t target,uint8_t lun,uint8_t channel)475 __ipmi_sensor_set_threshold(struct ipmi_intf *intf,
476 uint8_t num, uint8_t mask, uint8_t setting,
477 uint8_t target, uint8_t lun, uint8_t channel)
478 {
479 struct ipmi_rs *rsp;
480
481 rsp = ipmi_sensor_set_sensor_thresholds(intf, num, mask, setting,
482 target, lun, channel);
483
484 if (rsp == NULL) {
485 lprintf(LOG_ERR, "Error setting threshold");
486 return -1;
487 }
488 if (rsp->ccode > 0) {
489 lprintf(LOG_ERR, "Error setting threshold: %s",
490 val2str(rsp->ccode, completion_code_vals));
491 return -1;
492 }
493
494 return 0;
495 }
496
497 static uint8_t
__ipmi_sensor_threshold_value_to_raw(struct sdr_record_full_sensor * full,double value)498 __ipmi_sensor_threshold_value_to_raw(struct sdr_record_full_sensor *full, double value)
499 {
500 if (!UNITS_ARE_DISCRETE(&full->cmn)) { /* Has an analog reading */
501 /* Has an analog reading and supports mx+b */
502 return sdr_convert_sensor_value_to_raw(full, value);
503 }
504 else {
505 /* Does not have an analog reading and/or does not support mx+b */
506 if (value > 255) {
507 return 255;
508 }
509 else if (value < 0) {
510 return 0;
511 }
512 else {
513 return (uint8_t )value;
514 }
515 }
516 }
517
518 static int
ipmi_sensor_set_threshold(struct ipmi_intf * intf,int argc,char ** argv)519 ipmi_sensor_set_threshold(struct ipmi_intf *intf, int argc, char **argv)
520 {
521 char *id, *thresh;
522 uint8_t settingMask = 0;
523 double setting1 = 0.0, setting2 = 0.0, setting3 = 0.0;
524 int allUpper = 0, allLower = 0;
525 int ret = 0;
526 struct ipmi_rs *rsp;
527 int i =0;
528 double val[10] = {0};
529
530 struct sdr_record_list *sdr;
531
532 if (argc < 3 || strncmp(argv[0], "help", 4) == 0) {
533 print_sensor_thresh_usage();
534 return 0;
535 }
536
537 id = argv[0];
538 thresh = argv[1];
539
540 if (strncmp(thresh, "upper", 5) == 0) {
541 if (argc < 5) {
542 lprintf(LOG_ERR,
543 "usage: sensor thresh <id> upper <unc> <ucr> <unr>");
544 return -1;
545 }
546 allUpper = 1;
547 if (str2double(argv[2], &setting1) != 0) {
548 lprintf(LOG_ERR, "Given unc '%s' is invalid.",
549 argv[2]);
550 return (-1);
551 }
552 if (str2double(argv[3], &setting2) != 0) {
553 lprintf(LOG_ERR, "Given ucr '%s' is invalid.",
554 argv[3]);
555 return (-1);
556 }
557 if (str2double(argv[4], &setting3) != 0) {
558 lprintf(LOG_ERR, "Given unr '%s' is invalid.",
559 argv[4]);
560 return (-1);
561 }
562 } else if (strncmp(thresh, "lower", 5) == 0) {
563 if (argc < 5) {
564 lprintf(LOG_ERR,
565 "usage: sensor thresh <id> lower <lnr> <lcr> <lnc>");
566 return -1;
567 }
568 allLower = 1;
569 if (str2double(argv[2], &setting1) != 0) {
570 lprintf(LOG_ERR, "Given lnc '%s' is invalid.",
571 argv[2]);
572 return (-1);
573 }
574 if (str2double(argv[3], &setting2) != 0) {
575 lprintf(LOG_ERR, "Given lcr '%s' is invalid.",
576 argv[3]);
577 return (-1);
578 }
579 if (str2double(argv[4], &setting3) != 0) {
580 lprintf(LOG_ERR, "Given lnr '%s' is invalid.",
581 argv[4]);
582 return (-1);
583 }
584 } else {
585 if (strncmp(thresh, "unr", 3) == 0)
586 settingMask = UPPER_NON_RECOV_SPECIFIED;
587 else if (strncmp(thresh, "ucr", 3) == 0)
588 settingMask = UPPER_CRIT_SPECIFIED;
589 else if (strncmp(thresh, "unc", 3) == 0)
590 settingMask = UPPER_NON_CRIT_SPECIFIED;
591 else if (strncmp(thresh, "lnc", 3) == 0)
592 settingMask = LOWER_NON_CRIT_SPECIFIED;
593 else if (strncmp(thresh, "lcr", 3) == 0)
594 settingMask = LOWER_CRIT_SPECIFIED;
595 else if (strncmp(thresh, "lnr", 3) == 0)
596 settingMask = LOWER_NON_RECOV_SPECIFIED;
597 else {
598 lprintf(LOG_ERR,
599 "Valid threshold '%s' for sensor '%s' not specified!",
600 thresh, id);
601 return -1;
602 }
603 if (str2double(argv[2], &setting1) != 0) {
604 lprintf(LOG_ERR,
605 "Given %s threshold value '%s' is invalid.",
606 thresh, argv[2]);
607 return (-1);
608 }
609 }
610
611 printf("Locating sensor record '%s'...\n", id);
612
613 /* lookup by sensor name */
614 sdr = ipmi_sdr_find_sdr_byid(intf, id);
615 if (sdr == NULL) {
616 lprintf(LOG_ERR, "Sensor data record not found!");
617 return -1;
618 }
619
620 if (sdr->type != SDR_RECORD_TYPE_FULL_SENSOR) {
621 lprintf(LOG_ERR, "Invalid sensor type %02x", sdr->type);
622 return -1;
623 }
624
625 if (!IS_THRESHOLD_SENSOR(sdr->record.common)) {
626 lprintf(LOG_ERR, "Invalid sensor event type %02x", sdr->record.common->event_type);
627 return -1;
628 }
629
630
631 if (allUpper) {
632 settingMask = UPPER_NON_CRIT_SPECIFIED;
633 printf("Setting sensor \"%s\" %s threshold to %.3f\n",
634 sdr->record.full->id_string,
635 val2str(settingMask, threshold_vals), setting1);
636 ret = __ipmi_sensor_set_threshold(intf,
637 sdr->record.common->keys.
638 sensor_num, settingMask,
639 __ipmi_sensor_threshold_value_to_raw(sdr->record.full, setting1),
640 sdr->record.common->keys.owner_id,
641 sdr->record.common->keys.lun,
642 sdr->record.common->keys.channel);
643
644 settingMask = UPPER_CRIT_SPECIFIED;
645 printf("Setting sensor \"%s\" %s threshold to %.3f\n",
646 sdr->record.full->id_string,
647 val2str(settingMask, threshold_vals), setting2);
648 ret = __ipmi_sensor_set_threshold(intf,
649 sdr->record.common->keys.
650 sensor_num, settingMask,
651 __ipmi_sensor_threshold_value_to_raw(sdr->record.full, setting2),
652 sdr->record.common->keys.owner_id,
653 sdr->record.common->keys.lun,
654 sdr->record.common->keys.channel);
655
656 settingMask = UPPER_NON_RECOV_SPECIFIED;
657 printf("Setting sensor \"%s\" %s threshold to %.3f\n",
658 sdr->record.full->id_string,
659 val2str(settingMask, threshold_vals), setting3);
660 ret = __ipmi_sensor_set_threshold(intf,
661 sdr->record.common->keys.
662 sensor_num, settingMask,
663 __ipmi_sensor_threshold_value_to_raw(sdr->record.full, setting3),
664 sdr->record.common->keys.owner_id,
665 sdr->record.common->keys.lun,
666 sdr->record.common->keys.channel);
667 } else if (allLower) {
668 settingMask = LOWER_NON_RECOV_SPECIFIED;
669 printf("Setting sensor \"%s\" %s threshold to %.3f\n",
670 sdr->record.full->id_string,
671 val2str(settingMask, threshold_vals), setting1);
672 ret = __ipmi_sensor_set_threshold(intf,
673 sdr->record.common->keys.
674 sensor_num, settingMask,
675 __ipmi_sensor_threshold_value_to_raw(sdr->record.full, setting1),
676 sdr->record.common->keys.owner_id,
677 sdr->record.common->keys.lun,
678 sdr->record.common->keys.channel);
679
680 settingMask = LOWER_CRIT_SPECIFIED;
681 printf("Setting sensor \"%s\" %s threshold to %.3f\n",
682 sdr->record.full->id_string,
683 val2str(settingMask, threshold_vals), setting2);
684 ret = __ipmi_sensor_set_threshold(intf,
685 sdr->record.common->keys.
686 sensor_num, settingMask,
687 __ipmi_sensor_threshold_value_to_raw(sdr->record.full, setting2),
688 sdr->record.common->keys.owner_id,
689 sdr->record.common->keys.lun,
690 sdr->record.common->keys.channel);
691
692 settingMask = LOWER_NON_CRIT_SPECIFIED;
693 printf("Setting sensor \"%s\" %s threshold to %.3f\n",
694 sdr->record.full->id_string,
695 val2str(settingMask, threshold_vals), setting3);
696 ret = __ipmi_sensor_set_threshold(intf,
697 sdr->record.common->keys.
698 sensor_num, settingMask,
699 __ipmi_sensor_threshold_value_to_raw(sdr->record.full, setting3),
700 sdr->record.common->keys.owner_id,
701 sdr->record.common->keys.lun,
702 sdr->record.common->keys.channel);
703 } else {
704
705 /*
706 * Current implementation doesn't check for the valid setting of upper non critical and other thresholds.
707 * In the below logic:
708 * Get all the current reading of the sensor i.e. unc, uc, lc,lnc.
709 * Validate the values given by the user.
710 * If the values are not correct, then popup with the Error message and return.
711 */
712 /*
713 * Get current reading
714 */
715 rsp = ipmi_sdr_get_sensor_reading_ipmb(intf,
716 sdr->record.common->keys.sensor_num,
717 sdr->record.common->keys.owner_id,
718 sdr->record.common->keys.lun,sdr->record.common->keys.channel);
719 rsp = ipmi_sdr_get_sensor_thresholds(intf,
720 sdr->record.common->keys.sensor_num,
721 sdr->record.common->keys.owner_id,
722 sdr->record.common->keys.lun,
723 sdr->record.common->keys.channel);
724 if ((rsp == NULL) || (rsp->ccode > 0)) {
725 lprintf(LOG_ERR, "Sensor data record not found!");
726 return -1;
727 }
728 for(i=1;i<=6;i++) {
729 val[i] = sdr_convert_sensor_reading(sdr->record.full, rsp->data[i]);
730 if(val[i] < 0)
731 val[i] = 0;
732 }
733 /* Check for the valid Upper non recovarable Value.*/
734 if( (settingMask & UPPER_NON_RECOV_SPECIFIED) ) {
735
736 if( (rsp->data[0] & UPPER_NON_RECOV_SPECIFIED) &&
737 (( (rsp->data[0] & UPPER_CRIT_SPECIFIED) && ( setting1 <= val[5])) ||
738 ( (rsp->data[0] & UPPER_NON_CRIT_SPECIFIED) && ( setting1 <= val[4]))) )
739 {
740 lprintf(LOG_ERR, INVALID_THRESHOLD);
741 return -1;
742 }
743 } else if( (settingMask & UPPER_CRIT_SPECIFIED) ) { /* Check for the valid Upper critical Value.*/
744 if( (rsp->data[0] & UPPER_CRIT_SPECIFIED) &&
745 (((rsp->data[0] & UPPER_NON_RECOV_SPECIFIED)&& ( setting1 >= val[6])) ||
746 ((rsp->data[0] & UPPER_NON_CRIT_SPECIFIED)&&( setting1 <= val[4]))) )
747 {
748 lprintf(LOG_ERR, INVALID_THRESHOLD);
749 return -1;
750 }
751 } else if( (settingMask & UPPER_NON_CRIT_SPECIFIED) ) { /* Check for the valid Upper non critical Value.*/
752 if( (rsp->data[0] & UPPER_NON_CRIT_SPECIFIED) &&
753 (((rsp->data[0] & UPPER_NON_RECOV_SPECIFIED)&&( setting1 >= val[6])) ||
754 ((rsp->data[0] & UPPER_CRIT_SPECIFIED)&&( setting1 >= val[5])) ||
755 ((rsp->data[0] & LOWER_NON_CRIT_SPECIFIED)&&( setting1 <= val[1]))) )
756 {
757 lprintf(LOG_ERR, INVALID_THRESHOLD);
758 return -1;
759 }
760 } else if( (settingMask & LOWER_NON_CRIT_SPECIFIED) ) { /* Check for the valid lower non critical Value.*/
761 if( (rsp->data[0] & LOWER_NON_CRIT_SPECIFIED) &&
762 (((rsp->data[0] & LOWER_CRIT_SPECIFIED)&&( setting1 <= val[2])) ||
763 ((rsp->data[0] & LOWER_NON_RECOV_SPECIFIED)&&( setting1 <= val[3]))||
764 ((rsp->data[0] & UPPER_NON_CRIT_SPECIFIED)&&( setting1 >= val[4]))) )
765 {
766 lprintf(LOG_ERR, INVALID_THRESHOLD);
767 return -1;
768 }
769 } else if( (settingMask & LOWER_CRIT_SPECIFIED) ) { /* Check for the valid lower critical Value.*/
770 if( (rsp->data[0] & LOWER_CRIT_SPECIFIED) &&
771 (((rsp->data[0] & LOWER_NON_CRIT_SPECIFIED)&&( setting1 >= val[1])) ||
772 ((rsp->data[0] & LOWER_NON_RECOV_SPECIFIED)&&( setting1 <= val[3]))) )
773 {
774 lprintf(LOG_ERR, INVALID_THRESHOLD);
775 return -1;
776 }
777 } else if( (settingMask & LOWER_NON_RECOV_SPECIFIED) ) { /* Check for the valid lower non recovarable Value.*/
778 if( (rsp->data[0] & LOWER_NON_RECOV_SPECIFIED) &&
779 (((rsp->data[0] & LOWER_NON_CRIT_SPECIFIED)&&( setting1 >= val[1])) ||
780 ((rsp->data[0] & LOWER_CRIT_SPECIFIED)&&( setting1 >= val[2]))) )
781 {
782 lprintf(LOG_ERR, INVALID_THRESHOLD);
783 return -1;
784 }
785 } else { /* None of this Then Return with error messages.*/
786 lprintf(LOG_ERR, INVALID_THRESHOLD);
787 return -1;
788 }
789
790
791 printf("Setting sensor \"%s\" %s threshold to %.3f\n",
792 sdr->record.full->id_string,
793 val2str(settingMask, threshold_vals), setting1);
794
795 ret = __ipmi_sensor_set_threshold(intf,
796 sdr->record.common->keys.
797 sensor_num, settingMask,
798 __ipmi_sensor_threshold_value_to_raw(sdr->record.full, setting1),
799 sdr->record.common->keys.owner_id,
800 sdr->record.common->keys.lun,
801 sdr->record.common->keys.channel);
802 }
803
804 return ret;
805 }
806
807 static int
ipmi_sensor_get_reading(struct ipmi_intf * intf,int argc,char ** argv)808 ipmi_sensor_get_reading(struct ipmi_intf *intf, int argc, char **argv)
809 {
810 struct sdr_record_list *sdr;
811 int i, rc=0;
812
813 if (argc < 1 || strncmp(argv[0], "help", 4) == 0) {
814 lprintf(LOG_NOTICE, "sensor reading <id> ... [id]");
815 lprintf(LOG_NOTICE, " id : name of desired sensor");
816 return -1;
817 }
818
819 for (i = 0; i < argc; i++) {
820 sdr = ipmi_sdr_find_sdr_byid(intf, argv[i]);
821 if (sdr == NULL) {
822 lprintf(LOG_ERR, "Sensor \"%s\" not found!",
823 argv[i]);
824 rc = -1;
825 continue;
826 }
827
828 switch (sdr->type) {
829 case SDR_RECORD_TYPE_FULL_SENSOR:
830 case SDR_RECORD_TYPE_COMPACT_SENSOR:
831 {
832 struct sensor_reading *sr;
833 struct sdr_record_common_sensor *sensor = sdr->record.common;
834 sr = ipmi_sdr_read_sensor_value(intf, sensor, sdr->type, 3);
835
836 if (sr == NULL) {
837 rc = -1;
838 continue;
839 }
840
841 if (!sr->full)
842 continue;
843
844 if (!sr->s_reading_valid)
845 continue;
846
847 if (!sr->s_has_analog_value) {
848 lprintf(LOG_ERR, "Sensor \"%s\" is a discrete sensor!", argv[i]);
849 continue;
850 }
851 if (csv_output)
852 printf("%s,%s\n", argv[i], sr->s_a_str);
853 else
854 printf("%-16s | %s\n", argv[i], sr->s_a_str);
855
856 break;
857 }
858 default:
859 continue;
860 }
861 }
862
863 return rc;
864 }
865
866 static int
ipmi_sensor_get(struct ipmi_intf * intf,int argc,char ** argv)867 ipmi_sensor_get(struct ipmi_intf *intf, int argc, char **argv)
868 {
869 int i, v;
870 int rc = 0;
871 struct sdr_record_list *sdr;
872
873 if (argc < 1) {
874 lprintf(LOG_ERR, "Not enough parameters given.");
875 print_sensor_get_usage();
876 return (-1);
877 } else if (strcmp(argv[0], "help") == 0) {
878 print_sensor_get_usage();
879 return 0;
880 }
881 printf("Locating sensor record...\n");
882 /* lookup by sensor name */
883 for (i = 0; i < argc; i++) {
884 sdr = ipmi_sdr_find_sdr_byid(intf, argv[i]);
885 if (sdr == NULL) {
886 lprintf(LOG_ERR, "Sensor data record \"%s\" not found!",
887 argv[i]);
888 rc = -1;
889 continue;
890 }
891 /* need to set verbose level to 1 */
892 v = verbose;
893 verbose = 1;
894 switch (sdr->type) {
895 case SDR_RECORD_TYPE_FULL_SENSOR:
896 case SDR_RECORD_TYPE_COMPACT_SENSOR:
897 if (ipmi_sensor_print_fc(intf,
898 (struct sdr_record_common_sensor *) sdr->record.common,
899 sdr->type)) {
900 rc = -1;
901 }
902 break;
903 default:
904 if (ipmi_sdr_print_listentry(intf, sdr) < 0) {
905 rc = (-1);
906 }
907 break;
908 }
909 verbose = v;
910 sdr = NULL;
911 }
912 return rc;
913 }
914
915 int
ipmi_sensor_main(struct ipmi_intf * intf,int argc,char ** argv)916 ipmi_sensor_main(struct ipmi_intf *intf, int argc, char **argv)
917 {
918 int rc = 0;
919
920 if (argc == 0) {
921 rc = ipmi_sensor_list(intf);
922 } else if (strncmp(argv[0], "help", 4) == 0) {
923 lprintf(LOG_NOTICE, "Sensor Commands: list thresh get reading");
924 } else if (strncmp(argv[0], "list", 4) == 0) {
925 rc = ipmi_sensor_list(intf);
926 } else if (strncmp(argv[0], "thresh", 5) == 0) {
927 rc = ipmi_sensor_set_threshold(intf, argc - 1, &argv[1]);
928 } else if (strncmp(argv[0], "get", 3) == 0) {
929 rc = ipmi_sensor_get(intf, argc - 1, &argv[1]);
930 } else if (strncmp(argv[0], "reading", 7) == 0) {
931 rc = ipmi_sensor_get_reading(intf, argc - 1, &argv[1]);
932 } else {
933 lprintf(LOG_ERR, "Invalid sensor command: %s", argv[0]);
934 rc = -1;
935 }
936
937 return rc;
938 }
939
940 /* print_sensor_get_usage - print usage for # ipmitool sensor get NAC;
941 *
942 * @returns: void
943 */
944 void
print_sensor_get_usage()945 print_sensor_get_usage()
946 {
947 lprintf(LOG_NOTICE, "sensor get <id> ... [id]");
948 lprintf(LOG_NOTICE, " id : name of desired sensor");
949 }
950
951 /* print_sensor_thresh_set_usage - print usage for # ipmitool sensor thresh;
952 *
953 * @returns: void
954 */
955 void
print_sensor_thresh_usage()956 print_sensor_thresh_usage()
957 {
958 lprintf(LOG_NOTICE,
959 "sensor thresh <id> <threshold> <setting>");
960 lprintf(LOG_NOTICE,
961 " id : name of the sensor for which threshold is to be set");
962 lprintf(LOG_NOTICE,
963 " threshold : which threshold to set");
964 lprintf(LOG_NOTICE,
965 " unr = upper non-recoverable");
966 lprintf(LOG_NOTICE,
967 " ucr = upper critical");
968 lprintf(LOG_NOTICE,
969 " unc = upper non-critical");
970 lprintf(LOG_NOTICE,
971 " lnc = lower non-critical");
972 lprintf(LOG_NOTICE,
973 " lcr = lower critical");
974 lprintf(LOG_NOTICE,
975 " lnr = lower non-recoverable");
976 lprintf(LOG_NOTICE,
977 " setting : the value to set the threshold to");
978 lprintf(LOG_NOTICE,
979 "");
980 lprintf(LOG_NOTICE,
981 "sensor thresh <id> lower <lnr> <lcr> <lnc>");
982 lprintf(LOG_NOTICE,
983 " Set all lower thresholds at the same time");
984 lprintf(LOG_NOTICE,
985 "");
986 lprintf(LOG_NOTICE,
987 "sensor thresh <id> upper <unc> <ucr> <unr>");
988 lprintf(LOG_NOTICE,
989 " Set all upper thresholds at the same time");
990 lprintf(LOG_NOTICE, "");
991 }
992