1 /*
2 * ui.c
3 *
4 * MontaVista IPMI code, a simple curses UI for IPMI
5 *
6 * Author: MontaVista Software, Inc.
7 * Corey Minyard <minyard@mvista.com>
8 * source@mvista.com
9 *
10 * Copyright 2002,2003,2004 MontaVista Software Inc.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Lesser General Public License
14 * as published by the Free Software Foundation; either version 2 of
15 * the License, or (at your option) any later version.
16 *
17 *
18 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
19 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
20 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
23 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
24 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
26 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
27 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 *
29 * You should have received a copy of the GNU Lesser General Public
30 * License along with this program; if not, write to the Free
31 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
32 */
33
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
37 #include <curses.h>
38 #include <stdarg.h>
39 #include <errno.h>
40 #include <unistd.h>
41 #include <termios.h>
42 #include <fcntl.h>
43 #include <time.h>
44 #include <sys/time.h>
45 #include <ctype.h>
46
47 #include <OpenIPMI/ipmi_err.h>
48 #include <OpenIPMI/ipmi_msgbits.h>
49 #include <OpenIPMI/ipmi_mc.h>
50 #include <OpenIPMI/ipmiif.h>
51 #include <OpenIPMI/ipmi_ui.h>
52 #include <OpenIPMI/ipmi_fru.h>
53 #include <OpenIPMI/ipmi_pef.h>
54 #include <OpenIPMI/ipmi_lanparm.h>
55 #include <OpenIPMI/ipmi_pet.h>
56 #include <OpenIPMI/ipmi_conn.h>
57 #include <OpenIPMI/ipmi_debug.h>
58 #include <OpenIPMI/internal/ipmi_mc.h>
59
60 #include <OpenIPMI/internal/ipmi_malloc.h>
61 #include <OpenIPMI/internal/ipmi_event.h>
62
63 #include "ui_keypad.h"
64 #include "ui_command.h"
65
66 /* X/Open curses deprecates SVr4 vwprintw/vwscanw, but some still have it. */
67 #ifndef HAVE_VW_PRINTW
68 #define vw_printw vwprintw
69 #endif
70
71 WINDOW *main_win;
72 WINDOW *cmd_win;
73 WINDOW *stat_win;
74 WINDOW *log_pad;
75 WINDOW *dummy_pad;
76 WINDOW *display_pad;
77
78 int log_pad_top_line;
79 int display_pad_top_line;
80
81 keypad_t keymap;
82 command_t commands;
83
84 ipmi_domain_id_t domain_id;
85
86 os_handler_t *ipmi_ui_os_hnd;
87 ipmi_pef_t *pef;
88 ipmi_pef_config_t *pef_config;
89 ipmi_lanparm_t *lanparm;
90 ipmi_lan_config_t *lanparm_config;
91
92 static int full_screen;
93 struct termios old_termios;
94 int old_flags;
95
96 #define STATUS_WIN_LINES 2
97 #define STATUS_WIN_COLS COLS
98 #define STATUS_WIN_TOP 0
99 #define STATUS_WIN_LEFT 0
100
101 #define CMD_WIN_LINES 3
102 #define CMD_WIN_COLS COLS
103 #define CMD_WIN_LEFT 0
104 #define CMD_WIN_TOP (LINES-CMD_WIN_LINES)
105
106 #define DISPLAY_WIN_LINES (LINES - STATUS_WIN_LINES - CMD_WIN_LINES - 2)
107 #define DISPLAY_WIN_COLS (COLS/2-1)
108 #define DISPLAY_WIN_TOP (STATUS_WIN_LINES+1)
109 #define DISPLAY_WIN_LEFT 0
110 #define DISPLAY_WIN_RIGHT (COLS/2-2)
111 #define DISPLAY_WIN_BOTTOM (CMD_WIN_TOP-2)
112 #define NUM_DISPLAY_LINES 1024
113
114 #define LOG_WIN_LINES (LINES - STATUS_WIN_LINES - CMD_WIN_LINES - 2)
115 #define LOG_WIN_COLS (COLS-(COLS/2))
116 #define LOG_WIN_LEFT (COLS/2)
117 #define LOG_WIN_RIGHT (COLS-1)
118 #define LOG_WIN_TOP (STATUS_WIN_LINES+1)
119 #define LOG_WIN_BOTTOM (CMD_WIN_TOP-2)
120 #define NUM_LOG_LINES 1024
121
122 #define TOP_LINE STATUS_WIN_LINES
123 #define BOTTOM_LINE (LINES-CMD_WIN_LINES-1)
124 #define MID_COL (COLS/2-1)
125 #define MID_LINES (LINES - STATUS_WIN_LINES - CMD_WIN_LINES - 2)
126
127 enum scroll_wins_e { LOG_WIN_SCROLL, DISPLAY_WIN_SCROLL };
128
129 enum scroll_wins_e curr_win = LOG_WIN_SCROLL;
130
131 /* The current thing display in the display pad. */
132 enum {
133 DISPLAY_NONE, DISPLAY_SENSOR, DISPLAY_SENSORS,
134 DISPLAY_CONTROLS, DISPLAY_CONTROL, DISPLAY_ENTITIES, DISPLAY_MCS,
135 DISPLAY_MC,
136 DISPLAY_RSP, DISPLAY_SDRS, HELP, EVENTS, DISPLAY_ENTITY, DISPLAY_FRU
137 } curr_display_type;
138 ipmi_sensor_id_t curr_sensor_id;
139 ipmi_control_id_t curr_control_id;
140 typedef struct pos_s {int y; int x; } pos_t;
141 typedef struct thr_pos_s
142 {
143 int set;
144 pos_t value;
145 pos_t enabled;
146 pos_t oor;
147 } thr_pos_t;
148 thr_pos_t threshold_positions[6];
149
150 pos_t value_pos;
151 pos_t enabled_pos;
152 pos_t scanning_pos;
153 pos_t discr_assert_enab;
154 pos_t discr_deassert_enab;
155
156 ipmi_entity_id_t curr_entity_id;
157
158 static char *line_buffer = NULL;
159 static int line_buffer_max = 0;
160 static int line_buffer_pos = 0;
161
162 os_hnd_timer_id_t *redisplay_timer;
163
164 static void
conv_from_spaces(char * name)165 conv_from_spaces(char *name)
166 {
167 while (*name) {
168 if (*name == ' ')
169 *name = '~';
170 name++;
171 }
172 }
173
174 static void
conv_to_spaces(char * name)175 conv_to_spaces(char *name)
176 {
177 while (*name) {
178 if (*name == '~')
179 *name = ' ';
180 name++;
181 }
182 }
183
184 void
log_pad_refresh(int newlines)185 log_pad_refresh(int newlines)
186 {
187 if (full_screen) {
188 if (log_pad_top_line < 0)
189 log_pad_top_line = 0;
190
191 if (log_pad_top_line > (NUM_LOG_LINES - LOG_WIN_LINES))
192 log_pad_top_line = NUM_LOG_LINES - LOG_WIN_LINES;
193
194 if (log_pad_top_line != (NUM_LOG_LINES - LOG_WIN_LINES)) {
195 /* We are not at the bottom, so hold the same position. */
196 log_pad_top_line -= newlines;
197 }
198 prefresh(log_pad,
199 log_pad_top_line, 0,
200 LOG_WIN_TOP, LOG_WIN_LEFT,
201 LOG_WIN_BOTTOM, LOG_WIN_RIGHT);
202 wrefresh(cmd_win);
203 }
204 }
205
206 void
vlog_pad_out(const char * format,va_list ap)207 vlog_pad_out(const char *format, va_list ap)
208 {
209 if (full_screen)
210 vw_printw(log_pad, format, ap);
211 else
212 vprintf(format, ap);
213 }
214
215 void
log_pad_out(char * format,...)216 log_pad_out(char *format, ...)
217 {
218 va_list ap;
219
220 va_start(ap, format);
221 vlog_pad_out(format, ap);
222 va_end(ap);
223 }
224
225 void
display_pad_refresh(void)226 display_pad_refresh(void)
227 {
228 if (full_screen) {
229 if (display_pad_top_line >= NUM_DISPLAY_LINES)
230 display_pad_top_line = NUM_DISPLAY_LINES;
231
232 if (display_pad_top_line < 0)
233 display_pad_top_line = 0;
234
235 prefresh(display_pad,
236 display_pad_top_line, 0,
237 DISPLAY_WIN_TOP, DISPLAY_WIN_LEFT,
238 DISPLAY_WIN_BOTTOM, DISPLAY_WIN_RIGHT);
239 wrefresh(cmd_win);
240 }
241 }
242
243 void
display_pad_clear(void)244 display_pad_clear(void)
245 {
246 display_pad_top_line = 0;
247 if (full_screen) {
248 werase(display_pad);
249 wmove(display_pad, 0, 0);
250 }
251 }
252
253 void
display_pad_clear_nomove(void)254 display_pad_clear_nomove(void)
255 {
256 if (full_screen) {
257 werase(display_pad);
258 wmove(display_pad, 0, 0);
259 }
260 }
261
262 void
display_pad_out(char * format,...)263 display_pad_out(char *format, ...)
264 {
265 va_list ap;
266
267 va_start(ap, format);
268 if (full_screen)
269 vw_printw(display_pad, format, ap);
270 else
271 vprintf(format, ap);
272 va_end(ap);
273 }
274
275 void
cmd_win_out(char * format,...)276 cmd_win_out(char *format, ...)
277 {
278 va_list ap;
279
280 va_start(ap, format);
281 if (full_screen)
282 vw_printw(cmd_win, format, ap);
283 else
284 vprintf(format, ap);
285 va_end(ap);
286 }
287
288 void
cmd_win_refresh(void)289 cmd_win_refresh(void)
290 {
291 if (full_screen)
292 wrefresh(cmd_win);
293 else
294 fflush(stdout);
295 }
296
297 static int
get_uchar(char ** toks,unsigned char * val,char * errstr)298 get_uchar(char **toks, unsigned char *val, char *errstr)
299 {
300 char *str, *tmpstr;
301
302 str = strtok_r(NULL, " \t\n", toks);
303 if (!str) {
304 if (errstr)
305 cmd_win_out("No %s given\n", errstr);
306 return EINVAL;
307 }
308 *val = strtoul(str, &tmpstr, 16);
309 if (*tmpstr != '\0') {
310 if (errstr)
311 cmd_win_out("Invalid %s given\n", errstr);
312 return EINVAL;
313 }
314
315 return 0;
316 }
317
318 static int
get_uint(char ** toks,unsigned int * val,char * errstr)319 get_uint(char **toks, unsigned int *val, char *errstr)
320 {
321 char *str, *tmpstr;
322
323 str = strtok_r(NULL, " \t\n", toks);
324 if (!str) {
325 if (errstr)
326 cmd_win_out("No %s given\n", errstr);
327 return EINVAL;
328 }
329 *val = strtoul(str, &tmpstr, 16);
330 if (*tmpstr != '\0') {
331 if (errstr)
332 cmd_win_out("Invalid %s given\n", errstr);
333 return EINVAL;
334 }
335
336 return 0;
337 }
338
339 static int
get_ip_addr(char ** toks,struct in_addr * ip_addr,char * errstr)340 get_ip_addr(char **toks, struct in_addr *ip_addr, char *errstr)
341 {
342 uint32_t addr;
343 unsigned char val;
344 char *str, *tmpstr, *istr;
345 char *ntok;
346 int i;
347
348 str = strtok_r(NULL, " \t\n", toks);
349 if (!str) {
350 if (errstr)
351 cmd_win_out("No %s given\n", errstr);
352 return EINVAL;
353 }
354
355 addr = 0;
356 for (i=0; i<4; i++) {
357 istr = strtok_r(str, ".", &ntok);
358 str = NULL;
359 if (!istr) {
360 if (errstr)
361 cmd_win_out("%s: invalid IP address\n", errstr);
362 return EINVAL;
363 }
364 val = strtoul(istr, &tmpstr, 10);
365 if (*tmpstr != '\0') {
366 if (errstr)
367 cmd_win_out("%s: Invalid IP address\n", errstr);
368 return EINVAL;
369 }
370 addr = (addr << 8) | val;
371 }
372
373 ip_addr->s_addr = htonl(addr);
374 return 0;
375 }
376
377 static int
get_mac_addr(char ** toks,unsigned char * mac_addr,char * errstr)378 get_mac_addr(char **toks, unsigned char *mac_addr, char *errstr)
379 {
380 char *str, *tmpstr, *istr;
381 char *ntok;
382 int i;
383
384 str = strtok_r(NULL, " \t\n", toks);
385 if (!str) {
386 if (errstr)
387 cmd_win_out("No %s given\n", errstr);
388 return EINVAL;
389 }
390
391 for (i=0; i<6; i++) {
392 istr = strtok_r(str, ":", &ntok);
393 str = NULL;
394 if (!istr) {
395 if (errstr)
396 cmd_win_out("%s: invalid IP address\n", errstr);
397 return EINVAL;
398 }
399 mac_addr[i] = strtoul(istr, &tmpstr, 16);
400 if (*tmpstr != '\0') {
401 if (errstr)
402 cmd_win_out("%s: Invalid IP address\n", errstr);
403 return EINVAL;
404 }
405 }
406 return 0;
407 }
408
409 void
draw_lines()410 draw_lines()
411 {
412 werase(main_win);
413 wmove(main_win, TOP_LINE, 0);
414 whline(main_win, 0, COLS);
415 wmove(main_win, BOTTOM_LINE, 0);
416 whline(main_win, 0, COLS);
417 wmove(main_win, TOP_LINE, MID_COL);
418 wvline(main_win, ACS_TTEE, 1);
419 wmove(main_win, TOP_LINE+1, MID_COL);
420 wvline(main_win, 0, MID_LINES);
421 wmove(main_win, TOP_LINE+1+MID_LINES, MID_COL);
422 wvline(main_win, ACS_BTEE, 1);
423 wrefresh(main_win);
424 }
425
426 void
ui_vlog(const char * format,enum ipmi_log_type_e log_type,va_list ap)427 ui_vlog(const char *format, enum ipmi_log_type_e log_type, va_list ap)
428 {
429 int do_nl = 1;
430 struct timeval now;
431
432 ipmi_ui_os_hnd->get_real_time(ipmi_ui_os_hnd, &now);
433
434 if (full_screen) {
435 int x = 0, y = 0, old_x = 0, old_y = 0;
436 int max_x, max_y, i, j;
437
438 /* Generate the output to the dummy pad to see how many lines we
439 will use. */
440 getyx(dummy_pad, old_y, old_x);
441 switch(log_type)
442 {
443 case IPMI_LOG_INFO:
444 wprintw(dummy_pad, "%d.%6.6d: ", now.tv_sec, now.tv_usec);
445 wprintw(dummy_pad, "INFO: ");
446 break;
447
448 case IPMI_LOG_WARNING:
449 wprintw(dummy_pad, "%d.%6.6d: ", now.tv_sec, now.tv_usec);
450 wprintw(dummy_pad, "WARN: ");
451 break;
452
453 case IPMI_LOG_SEVERE:
454 wprintw(dummy_pad, "%d.%6.6d: ", now.tv_sec, now.tv_usec);
455 wprintw(dummy_pad, "SEVR: ");
456 break;
457
458 case IPMI_LOG_FATAL:
459 wprintw(dummy_pad, "%d.%6.6d: ", now.tv_sec, now.tv_usec);
460 wprintw(dummy_pad, "FATL: ");
461 break;
462
463 case IPMI_LOG_ERR_INFO:
464 wprintw(dummy_pad, "%d.%6.6d: ", now.tv_sec, now.tv_usec);
465 wprintw(dummy_pad, "EINF: ");
466 break;
467
468 case IPMI_LOG_DEBUG_START:
469 do_nl = 0;
470 /* FALLTHROUGH */
471 case IPMI_LOG_DEBUG:
472 wprintw(dummy_pad, "%d.%6.6d: ", now.tv_sec, now.tv_usec);
473 wprintw(dummy_pad, "DEBG: ");
474 break;
475
476 case IPMI_LOG_DEBUG_CONT:
477 do_nl = 0;
478 /* FALLTHROUGH */
479 case IPMI_LOG_DEBUG_END:
480 break;
481 }
482 vw_printw(dummy_pad, format, ap);
483 if (do_nl)
484 wprintw(dummy_pad, "\n");
485 getyx(dummy_pad, y, x);
486
487 if (old_y == y) {
488 for (j=old_x; j<x; j++)
489 waddch(log_pad, mvwinch(dummy_pad, y, j));
490 } else {
491 getmaxyx(dummy_pad, max_y, max_x);
492 for (j=old_x; j<max_x; j++)
493 waddch(log_pad, mvwinch(dummy_pad, old_y, j));
494 for (i=old_y+1; i<y; i++) {
495 for (j=0; j<max_x; j++)
496 waddch(log_pad, mvwinch(dummy_pad, i, j));
497 }
498 for (j=0; j<x; j++)
499 waddch(log_pad, mvwinch(dummy_pad, y, j));
500 }
501 y -= old_y;
502 wmove(dummy_pad, 0, x);
503 log_pad_refresh(y);
504 } else {
505 switch(log_type)
506 {
507 case IPMI_LOG_INFO:
508 log_pad_out("%d.%6.6d: ", now.tv_sec, now.tv_usec);
509 log_pad_out("INFO: ");
510 break;
511
512 case IPMI_LOG_WARNING:
513 log_pad_out("%d.%6.6d: ", now.tv_sec, now.tv_usec);
514 log_pad_out("WARN: ");
515 break;
516
517 case IPMI_LOG_SEVERE:
518 log_pad_out("%d.%6.6d: ", now.tv_sec, now.tv_usec);
519 log_pad_out("SEVR: ");
520 break;
521
522 case IPMI_LOG_FATAL:
523 log_pad_out("%d.%6.6d: ", now.tv_sec, now.tv_usec);
524 log_pad_out("FATL: ");
525 break;
526
527 case IPMI_LOG_ERR_INFO:
528 log_pad_out("%d.%6.6d: ", now.tv_sec, now.tv_usec);
529 log_pad_out("EINF: ");
530 break;
531
532 case IPMI_LOG_DEBUG_START:
533 do_nl = 0;
534 /* FALLTHROUGH */
535 case IPMI_LOG_DEBUG:
536 log_pad_out("%d.%6.6d: ", now.tv_sec, now.tv_usec);
537 log_pad_out("DEBG: ");
538 break;
539
540 case IPMI_LOG_DEBUG_CONT:
541 do_nl = 0;
542 /* FALLTHROUGH */
543 case IPMI_LOG_DEBUG_END:
544 break;
545 }
546
547 vlog_pad_out(format, ap);
548 if (do_nl)
549 log_pad_out("\n");
550 log_pad_refresh(0);
551 }
552 cmd_win_refresh();
553 }
554
555 void
ui_log(char * format,...)556 ui_log(char *format, ...)
557 {
558 int y = 0, x;
559 struct timeval now;
560 va_list ap;
561
562 ipmi_ui_os_hnd->get_real_time(ipmi_ui_os_hnd, &now);
563
564 va_start(ap, format);
565
566 if (full_screen) {
567 /* Generate the output to the dummy pad to see how many lines we
568 will use. */
569 wprintw(dummy_pad, "%d.%6.6d: ", now.tv_sec, now.tv_usec);
570 vw_printw(dummy_pad, format, ap);
571 getyx(dummy_pad, y, x);
572 wmove(dummy_pad, 0, x);
573 va_end(ap);
574 va_start(ap, format);
575 }
576
577 log_pad_out("%ld.%6.6ld: ", now.tv_sec, now.tv_usec);
578 vlog_pad_out(format, ap);
579 log_pad_refresh(y);
580 cmd_win_refresh();
581 va_end(ap);
582 }
583
584 void
leave(int rv,char * format,...)585 leave(int rv, char *format, ...)
586 {
587 va_list ap;
588
589 ipmi_shutdown();
590
591 ipmi_ui_os_hnd->stop_timer(ipmi_ui_os_hnd, redisplay_timer);
592 ipmi_ui_os_hnd->free_timer(ipmi_ui_os_hnd, redisplay_timer);
593
594 if (full_screen) {
595 endwin();
596 full_screen = 0;
597 } else {
598 tcsetattr(0, TCSADRAIN, &old_termios);
599 fcntl(0, F_SETFL, old_flags);
600 tcdrain(0);
601 }
602
603 if (pef_config) {
604 ipmi_pef_free_config(pef_config);
605 pef_config = NULL;
606 }
607 if (pef) {
608 ipmi_pef_destroy(pef, NULL, NULL);
609 pef = NULL;
610 }
611 if (lanparm_config) {
612 ipmi_lan_free_config(lanparm_config);
613 lanparm_config = NULL;
614 }
615 if (lanparm) {
616 ipmi_lanparm_destroy(lanparm, NULL, NULL);
617 lanparm = NULL;
618 }
619
620 if (line_buffer) {
621 ipmi_mem_free(line_buffer);
622 }
623 command_free(commands);
624 keypad_free(keymap);
625
626 ipmi_ui_os_hnd->free_os_handler(ipmi_ui_os_hnd);
627
628 va_start(ap, format);
629 vfprintf(stderr, format, ap);
630 va_end(ap);
631
632 ipmi_debug_malloc_cleanup();
633 exit(rv);
634 }
635
636 void
leave_err(int err,char * format,...)637 leave_err(int err, char *format, ...)
638 {
639 va_list ap;
640
641 if (full_screen)
642 endwin();
643 else {
644 tcsetattr(0, TCSADRAIN, &old_termios);
645 fcntl(0, F_SETFL, old_flags);
646 tcdrain(0);
647 }
648 ipmi_ui_os_hnd->free_os_handler(ipmi_ui_os_hnd);
649
650 va_start(ap, format);
651 vfprintf(stderr, format, ap);
652 va_end(ap);
653
654 if (IPMI_IS_OS_ERR(err)) {
655 fprintf(stderr, ": %s\n", strerror(IPMI_GET_OS_ERR(err)));
656 } else {
657 fprintf(stderr, ": IPMI Error %2.2x\n", IPMI_GET_IPMI_ERR(err));
658 }
659
660 ipmi_debug_malloc_cleanup();
661 exit(1);
662 }
663
664 #ifdef HAVE_WRESIZE
665 void
recalc_windows(void)666 recalc_windows(void)
667 {
668 draw_lines();
669
670 mvwin(stat_win, STATUS_WIN_TOP, STATUS_WIN_LEFT);
671 wresize(stat_win, STATUS_WIN_LINES, STATUS_WIN_COLS);
672 wrefresh(stat_win);
673 touchwin(stat_win);
674
675 wresize(display_pad, DISPLAY_WIN_LINES, DISPLAY_WIN_COLS);
676
677 mvwin(cmd_win, CMD_WIN_TOP, CMD_WIN_LEFT);
678 wresize(cmd_win, CMD_WIN_LINES, CMD_WIN_COLS);
679 wrefresh(cmd_win);
680 touchwin(cmd_win);
681
682 wresize(log_pad, NUM_LOG_LINES, LOG_WIN_COLS);
683 wresize(dummy_pad, NUM_LOG_LINES, LOG_WIN_COLS);
684
685 doupdate();
686
687 log_pad_refresh(0);
688 display_pad_refresh();
689 }
690 #endif
691
692 static
handle_user_char(int c)693 void handle_user_char(int c)
694 {
695 int err = keypad_handle_key(keymap, c, NULL);
696 if (err)
697 ui_log("Got error on char 0x%x 0%o %d\n", c, c, c);
698 }
699
700 void
user_input_ready(int fd,void * data,os_hnd_fd_id_t * id)701 user_input_ready(int fd, void *data, os_hnd_fd_id_t *id)
702 {
703 int c;
704
705 if (full_screen) {
706 c = wgetch(cmd_win);
707 while (c != ERR) {
708 handle_user_char(c);
709 c = wgetch(cmd_win);
710 }
711 } else {
712 char rc;
713 int count;
714
715 count = read(0, &rc, 1);
716 if (count > 0)
717 handle_user_char(rc);
718 }
719 }
720
721 static int
normal_char(int key,void * cb_data)722 normal_char(int key, void *cb_data)
723 {
724 char out[2];
725
726 if (line_buffer_pos >= line_buffer_max) {
727 char *new_line = ipmi_mem_alloc(line_buffer_max+10+1);
728 if (!new_line)
729 return ENOMEM;
730 line_buffer_max += 10;
731 if (line_buffer) {
732 memcpy(new_line, line_buffer, line_buffer_pos);
733 ipmi_mem_free(line_buffer);
734 }
735 line_buffer = new_line;
736 }
737 line_buffer[line_buffer_pos] = key;
738 line_buffer_pos++;
739 out[0] = key;
740 out[1] = '\0';
741 cmd_win_out(out);
742 cmd_win_refresh();
743 return 0;
744 }
745
746 static int
end_of_line(int key,void * cb_data)747 end_of_line(int key, void *cb_data)
748 {
749 int err;
750
751 if (!line_buffer)
752 return 0;
753
754 line_buffer[line_buffer_pos] = '\0';
755 cmd_win_out("\n");
756 err = command_handle(commands, line_buffer, NULL);
757 if (err)
758 cmd_win_out("Invalid command: %s\n> ", line_buffer);
759 else
760 cmd_win_out("> ");
761 line_buffer_pos = 0;
762 cmd_win_refresh();
763 return 0;
764 }
765
766 static int
backspace(int key,void * cb_data)767 backspace(int key, void *cb_data)
768 {
769 if (line_buffer_pos == 0)
770 return 0;
771
772 line_buffer_pos--;
773 cmd_win_out("\b \b");
774 cmd_win_refresh();
775 return 0;
776 }
777
778 static int
key_up(int key,void * cb_data)779 key_up(int key, void *cb_data)
780 {
781 return 0;
782 }
783
784 static int
key_down(int key,void * cb_data)785 key_down(int key, void *cb_data)
786 {
787 return 0;
788 }
789
790 static int
key_right(int key,void * cb_data)791 key_right(int key, void *cb_data)
792 {
793 return 0;
794 }
795
796 static int
key_left(int key,void * cb_data)797 key_left(int key, void *cb_data)
798 {
799 return 0;
800 }
801
802 static int
key_ppage(int key,void * cb_data)803 key_ppage(int key, void *cb_data)
804 {
805 if (curr_win == LOG_WIN_SCROLL) {
806 log_pad_top_line -= (LOG_WIN_LINES-1);
807 log_pad_refresh(0);
808 } else if (curr_win == DISPLAY_WIN_SCROLL) {
809 display_pad_top_line -= (DISPLAY_WIN_LINES-1);
810 display_pad_refresh();
811 }
812 return 0;
813 }
814
815 static int
key_npage(int key,void * cb_data)816 key_npage(int key, void *cb_data)
817 {
818 if (curr_win == LOG_WIN_SCROLL) {
819 log_pad_top_line += (LOG_WIN_LINES-1);
820 log_pad_refresh(0);
821 } else if (curr_win == DISPLAY_WIN_SCROLL) {
822 display_pad_top_line += (DISPLAY_WIN_LINES-1);
823 display_pad_refresh();
824 }
825 return 0;
826 }
827
828 static int leave_count = 0;
829
830 static void
final_leave(void * cb_data)831 final_leave(void *cb_data)
832 {
833 leave_count--;
834 if (leave_count == 0)
835 leave(0, "");
836 }
837
838 static void
leave_cmder(ipmi_domain_t * domain,void * cb_data)839 leave_cmder(ipmi_domain_t *domain, void *cb_data)
840 {
841 int rv;
842
843 rv = ipmi_domain_close(domain, final_leave, NULL);
844 if (!rv)
845 leave_count++;
846 }
847
848 static int
key_leave(int key,void * cb_data)849 key_leave(int key, void *cb_data)
850 {
851 ipmi_domain_iterate_domains(leave_cmder, NULL);
852 if (leave_count == 0)
853 leave(0, "");
854
855 return 0;
856 }
857
858 #ifdef HAVE_WRESIZE
859 static int
key_resize(int key,void * cb_data)860 key_resize(int key, void *cb_data)
861 {
862 recalc_windows();
863 return 0;
864 }
865 #endif
866
867 static int
key_set_display(int key,void * cb_data)868 key_set_display(int key, void *cb_data)
869 {
870 curr_win = DISPLAY_WIN_SCROLL;
871 return 0;
872 }
873
874 static int
key_set_log(int key,void * cb_data)875 key_set_log(int key, void *cb_data)
876 {
877 curr_win = LOG_WIN_SCROLL;
878 return 0;
879 }
880
881 /* Includes 3 3-byte fields (entity id, entity instance, and slave
882 address) and 1 2-byte field (channel) and three periods and the nil
883 char at the end and possible a leading "r" for device-relative. */
884 #define MAX_ENTITY_LOC_SIZE 16
885
886 /* Convert an entity to a locator for the entity. This is either:
887 <num>.<num> for an absolute entity, or
888 r<num>.<num>.<num>.<num> for a device-relative entity. */
889 static char *
get_entity_loc(ipmi_entity_t * entity,char * str,int strlen)890 get_entity_loc(ipmi_entity_t *entity, char *str, int strlen)
891 {
892 ipmi_entity_id_t id;
893
894 id = ipmi_entity_convert_to_id(entity);
895 if (id.entity_instance >= 0x60)
896 snprintf(str, strlen, "r%d.%d.%d.%d",
897 id.channel,
898 id.address,
899 id.entity_id,
900 id.entity_instance - 0x60);
901 else
902 snprintf(str, strlen, "%d.%d",
903 id.entity_id,
904 id.entity_instance);
905 return str;
906 }
907
908 static void
entities_handler(ipmi_entity_t * entity,void * cb_data)909 entities_handler(ipmi_entity_t *entity,
910 void *cb_data)
911 {
912 char *present;
913 char loc[MAX_ENTITY_LOC_SIZE];
914 char name[33];
915 enum ipmi_dlr_type_e type;
916 static char *ent_types[] = { "unknown", "mc", "fru",
917 "generic", "invalid" };
918
919 type = ipmi_entity_get_type(entity);
920 if (type > IPMI_ENTITY_GENERIC)
921 type = IPMI_ENTITY_GENERIC + 1;
922 curr_entity_id = ipmi_entity_convert_to_id(entity);
923 ipmi_entity_get_id(entity, name, 32);
924 if (strlen(name) == 0) {
925 strncpy(name, ipmi_entity_get_entity_id_string(entity), 32);
926 name[32] = '\0';
927 }
928 if (ipmi_entity_is_present(entity))
929 present = "present";
930 else
931 present = "not present";
932 display_pad_out(" %s (%s) %s %s\n",
933 get_entity_loc(entity, loc, sizeof(loc)),
934 name,
935 ent_types[type], present);
936 }
937
938 static void
entities_cmder(ipmi_domain_t * domain,void * cb_data)939 entities_cmder(ipmi_domain_t *domain, void *cb_data)
940 {
941 if (cb_data)
942 display_pad_clear_nomove();
943 else
944 display_pad_clear();
945 display_pad_out("Entities:\n");
946 ipmi_domain_iterate_entities(domain, entities_handler, NULL);
947 display_pad_refresh();
948 }
949
950 static int
entities_cmd(char * cmd,char ** toks,void * cb_data)951 entities_cmd(char *cmd, char **toks, void *cb_data)
952 {
953 int rv;
954
955 rv = ipmi_domain_pointer_cb(domain_id, entities_cmder, NULL);
956 if (rv) {
957 cmd_win_out("Unable to convert domain id to a pointer\n");
958 return 0;
959 }
960 curr_display_type = DISPLAY_ENTITIES;
961 return 0;
962 }
963
964 typedef void (*entity_handler_cb)(ipmi_entity_t *entity,
965 char **toks,
966 char **toks2,
967 void *cb_data);
968 struct ent_rec {
969 int id, instance, found;
970 int channel, address;
971 entity_handler_cb handler;
972 char **toks, **toks2;
973 void *cb_data;
974 };
975
976 static void
entity_searcher(ipmi_entity_t * entity,void * cb_data)977 entity_searcher(ipmi_entity_t *entity,
978 void *cb_data)
979 {
980 struct ent_rec *info = cb_data;
981 ipmi_entity_id_t id;
982
983 id = ipmi_entity_convert_to_id(entity);
984 if ((info->id == id.entity_id)
985 && (info->instance == id.entity_instance)
986 && (info->address == id.address)
987 && (info->channel == id.channel))
988 {
989 info->found = 1;
990 info->handler(entity, info->toks, info->toks2, info->cb_data);
991 }
992 }
993
994 static void
entity_finder_d(ipmi_domain_t * domain,void * cb_data)995 entity_finder_d(ipmi_domain_t *domain, void *cb_data)
996 {
997 ipmi_domain_iterate_entities(domain, entity_searcher, cb_data);
998 }
999
1000 int
entity_finder(char * cmd,char ** toks,entity_handler_cb handler,void * cb_data)1001 entity_finder(char *cmd, char **toks,
1002 entity_handler_cb handler,
1003 void *cb_data)
1004 {
1005 struct ent_rec info;
1006 char *ent_name;
1007 char *id_name, *instance_name, *toks2, *estr;
1008
1009 ent_name = strtok_r(NULL, " \t\n", toks);
1010 if (!ent_name) {
1011 cmd_win_out("No entity given\n");
1012 return EINVAL;
1013 }
1014
1015 if (ent_name[0] == 'r') {
1016 /* Device-relative address. */
1017 char *name;
1018 name = strtok_r(ent_name+1, ".", &toks2);
1019 info.channel = strtoul(name, &estr, 0);
1020 if (*estr != '\0') {
1021 cmd_win_out("Invalid entity channel given\n");
1022 return EINVAL;
1023 }
1024
1025 name = strtok_r(NULL, ".", &toks2);
1026 info.address = strtoul(name, &estr, 0);
1027 if (*estr != '\0') {
1028 cmd_win_out("Invalid entity address given\n");
1029 return EINVAL;
1030 }
1031
1032 id_name = strtok_r(NULL, ".", &toks2);
1033 } else {
1034 info.address = 0;
1035 info.channel = 0;
1036 id_name = strtok_r(ent_name, ".", &toks2);
1037 }
1038 instance_name = strtok_r(NULL, ".", &toks2);
1039 if (!instance_name) {
1040 cmd_win_out("Invalid entity given\n");
1041 return EINVAL;
1042 }
1043 info.id = strtoul(id_name, &estr, 0);
1044 if (*estr != '\0') {
1045 cmd_win_out("Invalid entity id given\n");
1046 return EINVAL;
1047 }
1048 info.instance = strtoul(instance_name, &estr, 0);
1049 if (*estr != '\0') {
1050 cmd_win_out("Invalid entity instance given\n");
1051 return EINVAL;
1052 }
1053 if (ent_name[0] == 'r')
1054 info.instance += 0x60;
1055
1056 info.found = 0;
1057
1058 info.handler = handler;
1059 info.cb_data = cb_data;
1060 info.toks = toks;
1061 info.toks2 = &toks2;
1062
1063 ipmi_domain_pointer_cb(domain_id, entity_finder_d, &info);
1064 if (!info.found) {
1065 if (ent_name[0] == 'r')
1066 cmd_win_out("Entity r%d.%d.%d.%d not found\n",
1067 info.channel, info.address, info.id,
1068 info.instance-0x60);
1069 else
1070 cmd_win_out("Entity %d.%d not found\n", info.id, info.instance);
1071
1072 return EINVAL;
1073 }
1074
1075 return 0;
1076 }
1077
1078 static void
entity_iterate_handler(ipmi_entity_t * o,ipmi_entity_t * entity,void * cb_data)1079 entity_iterate_handler(ipmi_entity_t *o,
1080 ipmi_entity_t *entity,
1081 void *cb_data)
1082 {
1083 char name[33];
1084 char loc[MAX_ENTITY_LOC_SIZE];
1085
1086 ipmi_entity_get_id(entity, name, 32);
1087
1088 display_pad_out(" %s (%s)\n",
1089 get_entity_loc(entity, loc, sizeof(loc)),
1090 name);
1091 }
1092
1093 static void
entity_handler(ipmi_entity_t * entity,char ** toks,char ** toks2,void * cb_data)1094 entity_handler(ipmi_entity_t *entity,
1095 char **toks,
1096 char **toks2,
1097 void *cb_data)
1098 {
1099 char *present;
1100 char name[33];
1101 char ename[IPMI_ENTITY_NAME_LEN];
1102 char loc[MAX_ENTITY_LOC_SIZE];
1103 enum ipmi_dlr_type_e type;
1104 static char *ent_types[] = { "unknown", "mc", "fru",
1105 "generic", "invalid" };
1106
1107 display_pad_clear();
1108 type = ipmi_entity_get_type(entity);
1109 if (type > IPMI_ENTITY_GENERIC)
1110 type = IPMI_ENTITY_GENERIC + 1;
1111 curr_entity_id = ipmi_entity_convert_to_id(entity);
1112 ipmi_entity_get_id(entity, name, 32);
1113 if (ipmi_entity_is_present(entity))
1114 present = "present";
1115 else
1116 present = "not present";
1117 display_pad_out("Entity %s (%s) %s\n",
1118 get_entity_loc(entity, loc, sizeof(loc)),
1119 name, present);
1120
1121 ipmi_entity_get_name(entity, ename, sizeof(ename));
1122 display_pad_out(" name = %s\n", ename);
1123
1124 display_pad_out(" type = %s\n", ent_types[type]);
1125 display_pad_out(" entity id string = %s\n",
1126 ipmi_entity_get_entity_id_string(entity));
1127 display_pad_out(" is%s fru\n",
1128 ipmi_entity_get_is_fru(entity) ? "" : " not");
1129 display_pad_out(" present sensor%s always there\n",
1130 ipmi_entity_get_presence_sensor_always_there(entity)
1131 ? "" : " not");
1132 if (ipmi_entity_get_is_child(entity)) {
1133 display_pad_out(" Parents:\n");
1134 ipmi_entity_iterate_parents(entity, entity_iterate_handler, NULL);
1135 }
1136 if (ipmi_entity_get_is_parent(entity)) {
1137 display_pad_out(" Children:\n");
1138 ipmi_entity_iterate_children(entity, entity_iterate_handler, NULL);
1139 }
1140
1141 switch (type) {
1142 case IPMI_ENTITY_MC:
1143 display_pad_out(" channel = 0x%x\n", ipmi_entity_get_channel(entity));
1144 display_pad_out(" lun = 0x%x\n", ipmi_entity_get_lun(entity));
1145 display_pad_out(" oem = 0x%x\n", ipmi_entity_get_oem(entity));
1146 display_pad_out(" slave_address = 0x%x\n",
1147 ipmi_entity_get_slave_address(entity));
1148 display_pad_out(" ACPI_system_power_notify_required = 0x%x\n",
1149 ipmi_entity_get_ACPI_system_power_notify_required(entity));
1150 display_pad_out(" ACPI_device_power_notify_required = 0x%x\n",
1151 ipmi_entity_get_ACPI_device_power_notify_required(entity));
1152 display_pad_out(" controller_logs_init_agent_errors = 0x%x\n",
1153 ipmi_entity_get_controller_logs_init_agent_errors(entity));
1154 display_pad_out(" log_init_agent_errors_accessing = 0x%x\n",
1155 ipmi_entity_get_log_init_agent_errors_accessing(entity));
1156 display_pad_out(" global_init = 0x%x\n",
1157 ipmi_entity_get_global_init(entity));
1158 display_pad_out(" chassis_device = 0x%x\n",
1159 ipmi_entity_get_chassis_device(entity));
1160 display_pad_out(" bridge = 0x%x\n",
1161 ipmi_entity_get_bridge(entity));
1162 display_pad_out(" IPMB_event_generator = 0x%x\n",
1163 ipmi_entity_get_IPMB_event_generator(entity));
1164 display_pad_out(" IPMB_event_receiver = 0x%x\n",
1165 ipmi_entity_get_IPMB_event_receiver(entity));
1166 display_pad_out(" FRU_inventory_device = 0x%x\n",
1167 ipmi_entity_get_FRU_inventory_device(entity));
1168 display_pad_out(" SEL_device = 0x%x\n",
1169 ipmi_entity_get_SEL_device(entity));
1170 display_pad_out(" SDR_repository_device = 0x%x\n",
1171 ipmi_entity_get_SDR_repository_device(entity));
1172 display_pad_out(" sensor_device = 0x%x\n",
1173 ipmi_entity_get_sensor_device(entity));
1174 break;
1175
1176 case IPMI_ENTITY_FRU:
1177 display_pad_out(" channel = 0x%x\n", ipmi_entity_get_channel(entity));
1178 display_pad_out(" lun = 0x%x\n", ipmi_entity_get_lun(entity));
1179 display_pad_out(" oem = 0x%x\n", ipmi_entity_get_oem(entity));
1180 display_pad_out(" access_address = 0x%x\n",
1181 ipmi_entity_get_access_address(entity));
1182 display_pad_out(" private_bus_id = 0x%x\n",
1183 ipmi_entity_get_private_bus_id(entity));
1184 display_pad_out(" device_type = 0x%x\n",
1185 ipmi_entity_get_device_type(entity));
1186 display_pad_out(" device_modifier = 0x%x\n",
1187 ipmi_entity_get_device_modifier(entity));
1188 display_pad_out(" is_logical_fru = 0x%x\n",
1189 ipmi_entity_get_is_logical_fru(entity));
1190 display_pad_out(" fru_device_id = 0x%x\n",
1191 ipmi_entity_get_fru_device_id(entity));
1192 break;
1193
1194 case IPMI_ENTITY_GENERIC:
1195 display_pad_out(" channel = 0x%x\n", ipmi_entity_get_channel(entity));
1196 display_pad_out(" lun = 0x%x\n", ipmi_entity_get_lun(entity));
1197 display_pad_out(" oem = 0x%x\n", ipmi_entity_get_oem(entity));
1198 display_pad_out(" access_address = 0x%x\n",
1199 ipmi_entity_get_access_address(entity));
1200 display_pad_out(" private_bus_id = 0x%x\n",
1201 ipmi_entity_get_private_bus_id(entity));
1202 display_pad_out(" device_type = 0x%x\n",
1203 ipmi_entity_get_device_type(entity));
1204 display_pad_out(" device_modifier = 0x%x\n",
1205 ipmi_entity_get_device_modifier(entity));
1206 display_pad_out(" slave_address = 0x%x\n",
1207 ipmi_entity_get_slave_address(entity));
1208 display_pad_out(" address_span = 0x%x\n",
1209 ipmi_entity_get_address_span(entity));
1210 break;
1211
1212 default:
1213 break;
1214 }
1215 display_pad_refresh();
1216 }
1217
1218 int
entity_cmd(char * cmd,char ** toks,void * cb_data)1219 entity_cmd(char *cmd, char **toks, void *cb_data)
1220 {
1221 entity_finder(cmd, toks, entity_handler, NULL);
1222 curr_display_type = DISPLAY_ENTITY;
1223 return 0;
1224 }
1225
1226
1227 static void
hs_get_act_time_cb(ipmi_entity_t * ent,int err,ipmi_timeout_t val,void * cb_data)1228 hs_get_act_time_cb(ipmi_entity_t *ent,
1229 int err,
1230 ipmi_timeout_t val,
1231 void *cb_data)
1232 {
1233 char loc[MAX_ENTITY_LOC_SIZE];
1234
1235 if (err) {
1236 ui_log("Could not get hot-swap act time: error 0x%x\n", err);
1237 return;
1238 }
1239
1240 ui_log("Hot-swap activate time for %s is %lld\n",
1241 get_entity_loc(ent, loc, sizeof(loc)), val);
1242 }
1243
1244 static void
hs_get_act_time_handler(ipmi_entity_t * entity,char ** toks,char ** toks2,void * cb_data)1245 hs_get_act_time_handler(ipmi_entity_t *entity,
1246 char **toks,
1247 char **toks2,
1248 void *cb_data)
1249 {
1250 int rv;
1251
1252 rv = ipmi_entity_get_auto_activate_time(entity, hs_get_act_time_cb, NULL);
1253 if (rv)
1254 cmd_win_out("Could not get auto-activate: error 0x%x\n", rv);
1255 }
1256
1257 int
hs_get_act_time(char * cmd,char ** toks,void * cb_data)1258 hs_get_act_time(char *cmd, char **toks, void *cb_data)
1259 {
1260 entity_finder(cmd, toks, hs_get_act_time_handler, NULL);
1261 return 0;
1262 }
1263
1264 static void
hs_set_act_time_cb(ipmi_entity_t * ent,int err,void * cb_data)1265 hs_set_act_time_cb(ipmi_entity_t *ent,
1266 int err,
1267 void *cb_data)
1268 {
1269 if (err)
1270 ui_log("Could not get hot-swap act time: error 0x%x\n", err);
1271 else
1272 ui_log("hot-swap act time set\n");
1273 }
1274
1275 static void
hs_set_act_time_handler(ipmi_entity_t * entity,char ** toks,char ** toks2,void * cb_data)1276 hs_set_act_time_handler(ipmi_entity_t *entity,
1277 char **toks,
1278 char **toks2,
1279 void *cb_data)
1280 {
1281 int rv;
1282 unsigned int timeout;
1283
1284 if (get_uint(toks, &timeout, "Hot swap activate time"))
1285 return;
1286
1287 rv = ipmi_entity_set_auto_activate_time(entity, timeout,
1288 hs_set_act_time_cb, NULL);
1289 if (rv)
1290 cmd_win_out("Could not set auto-activate: error 0x%x\n", rv);
1291 }
1292
1293 int
hs_set_act_time(char * cmd,char ** toks,void * cb_data)1294 hs_set_act_time(char *cmd, char **toks, void *cb_data)
1295 {
1296 entity_finder(cmd, toks, hs_set_act_time_handler, NULL);
1297 return 0;
1298 }
1299
1300 static void
hs_get_deact_time_cb(ipmi_entity_t * ent,int err,ipmi_timeout_t val,void * cb_data)1301 hs_get_deact_time_cb(ipmi_entity_t *ent,
1302 int err,
1303 ipmi_timeout_t val,
1304 void *cb_data)
1305 {
1306 char loc[MAX_ENTITY_LOC_SIZE];
1307
1308 if (err) {
1309 ui_log("Could not get hot-swap deact time: error 0x%x\n", err);
1310 return;
1311 }
1312
1313 ui_log("Hot-swap deactivate time for %s is %lld\n",
1314 get_entity_loc(ent, loc, sizeof(loc)), val);
1315 }
1316
1317 static void
hs_get_deact_time_handler(ipmi_entity_t * entity,char ** toks,char ** toks2,void * cb_data)1318 hs_get_deact_time_handler(ipmi_entity_t *entity,
1319 char **toks,
1320 char **toks2,
1321 void *cb_data)
1322 {
1323 int rv;
1324
1325 rv = ipmi_entity_get_auto_deactivate_time(entity, hs_get_deact_time_cb, NULL);
1326 if (rv)
1327 cmd_win_out("Could not get auto-deactivate: error 0x%x\n", rv);
1328 }
1329
1330 int
hs_get_deact_time(char * cmd,char ** toks,void * cb_data)1331 hs_get_deact_time(char *cmd, char **toks, void *cb_data)
1332 {
1333 entity_finder(cmd, toks, hs_get_deact_time_handler, NULL);
1334 return 0;
1335 }
1336
1337 static void
hs_set_deact_time_cb(ipmi_entity_t * ent,int err,void * cb_data)1338 hs_set_deact_time_cb(ipmi_entity_t *ent,
1339 int err,
1340 void *cb_data)
1341 {
1342 if (err)
1343 ui_log("Could not get hot-swap deact time: error 0x%x\n", err);
1344 else
1345 ui_log("hot-swap deact time set\n");
1346 }
1347
1348 static void
hs_set_deact_time_handler(ipmi_entity_t * entity,char ** toks,char ** toks2,void * cb_data)1349 hs_set_deact_time_handler(ipmi_entity_t *entity,
1350 char **toks,
1351 char **toks2,
1352 void *cb_data)
1353 {
1354 int rv;
1355 unsigned int timeout;
1356
1357 if (get_uint(toks, &timeout, "Hot swap deactivate time"))
1358 return;
1359
1360 rv = ipmi_entity_set_auto_deactivate_time(entity, timeout,
1361 hs_set_deact_time_cb, NULL);
1362 if (rv)
1363 cmd_win_out("Could not set auto-deactivate: error 0x%x\n", rv);
1364 }
1365
1366 int
hs_set_deact_time(char * cmd,char ** toks,void * cb_data)1367 hs_set_deact_time(char *cmd, char **toks, void *cb_data)
1368 {
1369 entity_finder(cmd, toks, hs_set_deact_time_handler, NULL);
1370 return 0;
1371 }
1372
1373 static void
hs_activation_request_cb(ipmi_entity_t * ent,int err,void * cb_data)1374 hs_activation_request_cb(ipmi_entity_t *ent,
1375 int err,
1376 void *cb_data)
1377 {
1378 if (err)
1379 ui_log("Could not activate entity: error 0x%x\n", err);
1380 else
1381 ui_log("entity activated\n");
1382 }
1383
1384 static void
hs_activation_request_handler(ipmi_entity_t * entity,char ** toks,char ** toks2,void * cb_data)1385 hs_activation_request_handler(ipmi_entity_t *entity,
1386 char **toks,
1387 char **toks2,
1388 void *cb_data)
1389 {
1390 int rv;
1391
1392 rv = ipmi_entity_set_activation_requested(entity,
1393 hs_activation_request_cb,
1394 NULL);
1395 if (rv)
1396 cmd_win_out("Could not set activation requested: error 0x%x\n", rv);
1397 }
1398
1399 static int
hs_activation_request(char * cmd,char ** toks,void * cb_data)1400 hs_activation_request(char *cmd, char **toks, void *cb_data)
1401 {
1402 entity_finder(cmd, toks, hs_activation_request_handler, NULL);
1403 return 0;
1404 }
1405
1406 static void
hs_activate_cb(ipmi_entity_t * ent,int err,void * cb_data)1407 hs_activate_cb(ipmi_entity_t *ent,
1408 int err,
1409 void *cb_data)
1410 {
1411 if (err)
1412 ui_log("Could not activate entity: error 0x%x\n", err);
1413 else
1414 ui_log("entity activated\n");
1415 }
1416
1417 static void
hs_activate_handler(ipmi_entity_t * entity,char ** toks,char ** toks2,void * cb_data)1418 hs_activate_handler(ipmi_entity_t *entity,
1419 char **toks,
1420 char **toks2,
1421 void *cb_data)
1422 {
1423 int rv;
1424
1425 rv = ipmi_entity_activate(entity, hs_activate_cb, NULL);
1426 if (rv)
1427 cmd_win_out("Could not activate entity: error 0x%x\n", rv);
1428 }
1429
1430 int
hs_activate(char * cmd,char ** toks,void * cb_data)1431 hs_activate(char *cmd, char **toks, void *cb_data)
1432 {
1433 entity_finder(cmd, toks, hs_activate_handler, NULL);
1434 return 0;
1435 }
1436
1437 static void
hs_deactivate_cb(ipmi_entity_t * ent,int err,void * cb_data)1438 hs_deactivate_cb(ipmi_entity_t *ent,
1439 int err,
1440 void *cb_data)
1441 {
1442 if (err)
1443 ui_log("Could not deactivate entity: error 0x%x\n", err);
1444 else
1445 ui_log("entity deactivated\n");
1446 }
1447
1448 static void
hs_deactivate_handler(ipmi_entity_t * entity,char ** toks,char ** toks2,void * cb_data)1449 hs_deactivate_handler(ipmi_entity_t *entity,
1450 char **toks,
1451 char **toks2,
1452 void *cb_data)
1453 {
1454 int rv;
1455
1456 rv = ipmi_entity_deactivate(entity, hs_deactivate_cb, NULL);
1457 if (rv)
1458 cmd_win_out("Could not deactivate entity: error 0x%x\n", rv);
1459 }
1460
1461 int
hs_deactivate(char * cmd,char ** toks,void * cb_data)1462 hs_deactivate(char *cmd, char **toks, void *cb_data)
1463 {
1464 entity_finder(cmd, toks, hs_deactivate_handler, NULL);
1465 return 0;
1466 }
1467
1468 static void
hs_state_cb(ipmi_entity_t * ent,int err,enum ipmi_hot_swap_states state,void * cb_data)1469 hs_state_cb(ipmi_entity_t *ent,
1470 int err,
1471 enum ipmi_hot_swap_states state,
1472 void *cb_data)
1473 {
1474 if (err)
1475 ui_log("Could not get hot-swap state: error 0x%x\n", err);
1476 else
1477 ui_log("Hot-swap state is %s\n", ipmi_hot_swap_state_name(state));
1478 }
1479
1480 static void
hs_state_handler(ipmi_entity_t * entity,char ** toks,char ** toks2,void * cb_data)1481 hs_state_handler(ipmi_entity_t *entity,
1482 char **toks,
1483 char **toks2,
1484 void *cb_data)
1485 {
1486 int rv;
1487
1488 rv = ipmi_entity_get_hot_swap_state(entity, hs_state_cb, NULL);
1489 if (rv)
1490 cmd_win_out("Could not get entity state: error 0x%x\n", rv);
1491 }
1492
1493 int
hs_state(char * cmd,char ** toks,void * cb_data)1494 hs_state(char *cmd, char **toks, void *cb_data)
1495 {
1496 entity_finder(cmd, toks, hs_state_handler, NULL);
1497 return 0;
1498 }
1499
1500 static void
hs_check_ent(ipmi_entity_t * entity,void * cb_data)1501 hs_check_ent(ipmi_entity_t *entity, void *cb_data)
1502 {
1503 ipmi_entity_check_hot_swap_state(entity);
1504 }
1505
1506 static void
hs_check_cmder(ipmi_domain_t * domain,void * cb_data)1507 hs_check_cmder(ipmi_domain_t *domain, void *cb_data)
1508 {
1509 ipmi_domain_iterate_entities(domain, hs_check_ent, NULL);
1510 }
1511
1512 int
hs_check_cmd(char * cmd,char ** toks,void * cb_data)1513 hs_check_cmd(char *cmd, char **toks, void *cb_data)
1514 {
1515 int rv;
1516
1517 rv = ipmi_domain_pointer_cb(domain_id, hs_check_cmder, NULL);
1518 if (rv) {
1519 cmd_win_out("Unable to convert domain id to a pointer\n");
1520 return 0;
1521 }
1522
1523 return 0;
1524 }
1525
1526
1527
1528 static void
sensors_handler(ipmi_entity_t * entity,ipmi_sensor_t * sensor,void * cb_data)1529 sensors_handler(ipmi_entity_t *entity, ipmi_sensor_t *sensor, void *cb_data)
1530 {
1531 char name[33];
1532 char name2[33];
1533 char loc[MAX_ENTITY_LOC_SIZE];
1534
1535 ipmi_sensor_get_id(sensor, name, 33);
1536 strcpy(name2, name);
1537 conv_from_spaces(name2);
1538 display_pad_out(" %s.%s - %s\n",
1539 get_entity_loc(entity, loc, sizeof(loc)),
1540 name2, name);
1541 }
1542
1543 static void
found_entity_for_sensors(ipmi_entity_t * entity,char ** toks,char ** toks2,void * cb_data)1544 found_entity_for_sensors(ipmi_entity_t *entity,
1545 char **toks,
1546 char **toks2,
1547 void *cb_data)
1548 {
1549 char loc[MAX_ENTITY_LOC_SIZE];
1550
1551 curr_display_type = DISPLAY_SENSORS;
1552 display_pad_clear();
1553 display_pad_out("Sensors for entity %s:\n",
1554 get_entity_loc(entity, loc, sizeof(loc)));
1555 ipmi_entity_iterate_sensors(entity, sensors_handler, NULL);
1556 display_pad_refresh();
1557 }
1558
1559 int
sensors_cmd(char * cmd,char ** toks,void * cb_data)1560 sensors_cmd(char *cmd, char **toks, void *cb_data)
1561 {
1562 entity_finder(cmd, toks, found_entity_for_sensors, NULL);
1563 return 0;
1564 }
1565
1566 struct sensor_info {
1567 int found;
1568 char *name;
1569 };
1570
1571 /* Has this sensor been displayed yet? */
1572 int sensor_displayed;
1573
1574 /* Decrement whenever the sensor is not displayed and data is
1575 recevied, when this hits zero it's time to display. */
1576 int sensor_ops_to_read_count;
1577
1578 /* Return value from ipmi_states_get or ipmi_reading_get. */
1579 int sensor_read_err;
1580
1581 /* Values from ipmi_reading_get. */
1582 enum ipmi_value_present_e sensor_value_present;
1583 unsigned int sensor_raw_val;
1584 double sensor_val;
1585
1586 /* Values from ipmi_states_get and ipmi_reading_get. */
1587 ipmi_states_t *sensor_states;
1588
1589 /* Values from ipmi_sensor_event_enables_get. */
1590 int sensor_event_states_err;
1591 ipmi_event_state_t *sensor_event_states;
1592
1593 /* Values from ipmi_thresholds_get */
1594 int sensor_read_thresh_err;
1595 ipmi_thresholds_t *sensor_thresholds;
1596
1597 static void
display_sensor(ipmi_entity_t * entity,ipmi_sensor_t * sensor)1598 display_sensor(ipmi_entity_t *entity, ipmi_sensor_t *sensor)
1599 {
1600 char loc[MAX_ENTITY_LOC_SIZE];
1601 char name[33];
1602 char sname[IPMI_SENSOR_NAME_LEN];
1603 int rv;
1604
1605 if (sensor_displayed)
1606 return;
1607
1608 sensor_ops_to_read_count--;
1609 if (sensor_ops_to_read_count > 0)
1610 return;
1611
1612 sensor_displayed = 1;
1613
1614 ipmi_sensor_get_name(sensor, sname, sizeof(sname));
1615
1616 ipmi_sensor_get_id(sensor, name, 33);
1617 display_pad_clear();
1618
1619 conv_from_spaces(name);
1620 display_pad_out("Sensor %s.%s:\n",
1621 get_entity_loc(entity, loc, sizeof(loc)),
1622 name);
1623 if (ipmi_sensor_get_ignore_if_no_entity(sensor))
1624 display_pad_out(" ignore if entity not present\n");
1625 else
1626 display_pad_out(" still there if entity not present\n");
1627 display_pad_out(" name = %s\n", sname);
1628 display_pad_out(" value = ");
1629 getyx(display_pad, value_pos.y, value_pos.x);
1630 if (!ipmi_entity_is_present(entity)
1631 && ipmi_sensor_get_ignore_if_no_entity(sensor))
1632 {
1633 display_pad_out("not present");
1634 } else {
1635 if (sensor_read_err) {
1636 display_pad_out("unreadable");
1637 } else if (ipmi_sensor_get_event_reading_type(sensor)
1638 == IPMI_EVENT_READING_TYPE_THRESHOLD)
1639 {
1640 if (sensor_value_present == IPMI_BOTH_VALUES_PRESENT)
1641 display_pad_out("%f (%2.2x)", sensor_val, sensor_raw_val);
1642 else if (sensor_value_present == IPMI_RAW_VALUE_PRESENT)
1643 display_pad_out("0x%x (RAW)", sensor_raw_val);
1644 else
1645 display_pad_out("unreadable");
1646 } else {
1647 int i;
1648 for (i=0; i<15; i++) {
1649 int val;
1650 val = ipmi_is_state_set(sensor_states, i);
1651 display_pad_out("%d", val != 0);
1652 }
1653 }
1654 }
1655 display_pad_out("\n Events = ");
1656 getyx(display_pad, enabled_pos.y, enabled_pos.x);
1657 if (sensor_event_states_err)
1658 display_pad_out("? ");
1659 else {
1660 int global_enable;
1661 global_enable = ipmi_event_state_get_events_enabled
1662 (sensor_event_states);
1663 if (global_enable)
1664 display_pad_out("enabled");
1665 else
1666 display_pad_out("disabled");
1667 }
1668 display_pad_out("\n Scanning = ");
1669 getyx(display_pad, scanning_pos.y, scanning_pos.x);
1670 if (sensor_event_states_err)
1671 display_pad_out("? ");
1672 else {
1673 int scanning_enable;
1674 scanning_enable = ipmi_event_state_get_scanning_enabled
1675 (sensor_event_states);
1676 if (scanning_enable)
1677 display_pad_out("enabled");
1678 else
1679 display_pad_out("disabled");
1680 }
1681 display_pad_out("\n Hysteresis = ");
1682 switch (ipmi_sensor_get_hysteresis_support(sensor)) {
1683 case IPMI_HYSTERESIS_SUPPORT_NONE: display_pad_out("none"); break;
1684 case IPMI_HYSTERESIS_SUPPORT_READABLE: display_pad_out("readable"); break;
1685 case IPMI_HYSTERESIS_SUPPORT_SETTABLE: display_pad_out("settable"); break;
1686 case IPMI_HYSTERESIS_SUPPORT_FIXED: display_pad_out("fixed"); break;
1687 default: display_pad_out("invalid"); break;
1688 }
1689 display_pad_out("\n");
1690 display_pad_out(" sensor type = %s (0x%2.2x)\n",
1691 ipmi_sensor_get_sensor_type_string(sensor),
1692 ipmi_sensor_get_sensor_type(sensor));
1693 display_pad_out(" event/reading type = %s (0x%2.2x)\n",
1694 ipmi_sensor_get_event_reading_type_string(sensor),
1695 ipmi_sensor_get_event_reading_type(sensor));
1696
1697 if (ipmi_sensor_get_event_reading_type(sensor)
1698 == IPMI_EVENT_READING_TYPE_THRESHOLD)
1699 {
1700 enum ipmi_thresh_e t;
1701 double val;
1702
1703 display_pad_out(" units = %s%s",
1704 ipmi_sensor_get_base_unit_string(sensor),
1705 ipmi_sensor_get_rate_unit_string(sensor));
1706 switch(ipmi_sensor_get_modifier_unit_use(sensor)) {
1707 case IPMI_MODIFIER_UNIT_BASE_DIV_MOD:
1708 display_pad_out("/%s",
1709 ipmi_sensor_get_modifier_unit_string(sensor));
1710 break;
1711
1712 case IPMI_MODIFIER_UNIT_BASE_MULT_MOD:
1713 display_pad_out("*%s",
1714 ipmi_sensor_get_modifier_unit_string(sensor));
1715 break;
1716
1717 case IPMI_MODIFIER_UNIT_NONE:
1718 break;
1719 }
1720 display_pad_out("\n");
1721
1722 rv = ipmi_sensor_get_nominal_reading(sensor, &val);
1723 if (!rv) display_pad_out(" nominal = %f\n", val);
1724
1725 rv = ipmi_sensor_get_normal_min(sensor, &val);
1726 if (!rv) display_pad_out(" normal_min = %f\n", val);
1727
1728 rv = ipmi_sensor_get_normal_max(sensor, &val);
1729 if (!rv) display_pad_out(" normal_max = %f\n", val);
1730
1731 rv = ipmi_sensor_get_sensor_min(sensor, &val);
1732 if (!rv) display_pad_out(" sensor_min = %f\n", val);
1733
1734 rv = ipmi_sensor_get_sensor_max(sensor, &val);
1735 if (!rv) display_pad_out(" sensor_max = %f\n", val);
1736
1737 display_pad_out("Thresholds:\n");
1738 for (t=IPMI_LOWER_NON_CRITICAL; t<=IPMI_UPPER_NON_RECOVERABLE; t++){
1739 int settable, readable;
1740 int i;
1741 int assert_sup[2], deassert_sup[2];
1742 int anything_set = 0;
1743
1744 ipmi_sensor_threshold_settable(sensor, t, &settable);
1745 anything_set |= settable;
1746 ipmi_sensor_threshold_readable(sensor, t, &readable);
1747 anything_set |= readable;
1748 for (i=0; i<=1; i++) {
1749 ipmi_sensor_threshold_event_supported(
1750 sensor, t, i, IPMI_ASSERTION, &(assert_sup[i]));
1751 anything_set |= assert_sup[i];
1752 ipmi_sensor_threshold_event_supported(
1753 sensor, t, i, IPMI_DEASSERTION, &(deassert_sup[i]));
1754 anything_set |= deassert_sup[i];
1755 }
1756 if (anything_set) {
1757 display_pad_out(" %s:", ipmi_get_threshold_string(t));
1758 threshold_positions[t].set = 1;
1759 display_pad_out("\n available: ");
1760 if (readable) display_pad_out("R");
1761 else display_pad_out(" ");
1762 if (settable) display_pad_out("W");
1763 else display_pad_out(" ");
1764 if (assert_sup[0]) display_pad_out("L^");
1765 else display_pad_out(" ");
1766 if (deassert_sup[0]) display_pad_out("Lv");
1767 else display_pad_out(" ");
1768 if (assert_sup[1]) display_pad_out("H^");
1769 else display_pad_out(" ");
1770 if (deassert_sup[1]) display_pad_out("Hv");
1771 else display_pad_out(" ");
1772 display_pad_out("\n enabled: ");
1773 getyx(display_pad,
1774 threshold_positions[t].enabled.y,
1775 threshold_positions[t].enabled.x);
1776 if (sensor_event_states_err)
1777 display_pad_out("? ");
1778 else {
1779 if (ipmi_is_threshold_event_set(sensor_event_states, t,
1780 IPMI_GOING_LOW,
1781 IPMI_ASSERTION))
1782 display_pad_out("L^");
1783 else
1784 display_pad_out(" ");
1785 if (ipmi_is_threshold_event_set(sensor_event_states, t,
1786 IPMI_GOING_LOW,
1787 IPMI_DEASSERTION))
1788 display_pad_out("Lv");
1789 else
1790 display_pad_out(" ");
1791 if (ipmi_is_threshold_event_set(sensor_event_states, t,
1792 IPMI_GOING_HIGH,
1793 IPMI_ASSERTION))
1794 display_pad_out("H^");
1795 else
1796 display_pad_out(" ");
1797 if (ipmi_is_threshold_event_set(sensor_event_states, t,
1798 IPMI_GOING_HIGH,
1799 IPMI_DEASSERTION))
1800 display_pad_out("HV");
1801 else
1802 display_pad_out(" ");
1803 }
1804
1805 display_pad_out("\n value: ");
1806 getyx(display_pad,
1807 threshold_positions[t].value.y,
1808 threshold_positions[t].value.x);
1809 if (sensor_read_thresh_err)
1810 display_pad_out("?");
1811 else {
1812 double val;
1813 rv = ipmi_threshold_get(sensor_thresholds, t, &val);
1814 if (rv)
1815 display_pad_out("?", val);
1816 else
1817 display_pad_out("%f", val);
1818 }
1819 display_pad_out("\n out of range: ");
1820 getyx(display_pad,
1821 threshold_positions[t].oor.y,
1822 threshold_positions[t].oor.x);
1823 if (!sensor_read_err) {
1824 if (ipmi_is_threshold_out_of_range(sensor_states, t))
1825 display_pad_out("true ");
1826 else
1827 display_pad_out("false");
1828 }
1829 display_pad_out("\n");
1830 } else {
1831 threshold_positions[t].set = 0;
1832 }
1833 }
1834 } else {
1835 int val;
1836 int i;
1837
1838 /* A discrete sensor. */
1839 display_pad_out("\n Assertion: ");
1840 display_pad_out("\n available: ");
1841 for (i=0; i<15; i++) {
1842 ipmi_sensor_discrete_event_supported(sensor,
1843 i,
1844 IPMI_ASSERTION,
1845 &val);
1846 display_pad_out("%d", val != 0);
1847 }
1848 display_pad_out("\n enabled: ");
1849 getyx(display_pad, discr_assert_enab.y, discr_assert_enab.x);
1850 if (sensor_event_states_err)
1851 display_pad_out("?");
1852 else {
1853 for (i=0; i<15; i++) {
1854 val = ipmi_is_discrete_event_set(sensor_event_states,
1855 i, IPMI_ASSERTION);
1856 display_pad_out("%d", val != 0);
1857 }
1858 }
1859
1860 display_pad_out("\n Deasertion: ");
1861 display_pad_out("\n available: ");
1862 for (i=0; i<15; i++) {
1863 ipmi_sensor_discrete_event_supported(sensor,
1864 i,
1865 IPMI_DEASSERTION,
1866 &val);
1867 display_pad_out("%d", val != 0);
1868 }
1869 display_pad_out("\n enabled: ");
1870 getyx(display_pad, discr_deassert_enab.y, discr_deassert_enab.x);
1871 if (sensor_event_states_err)
1872 display_pad_out("?");
1873 else {
1874 for (i=0; i<15; i++) {
1875 val = ipmi_is_discrete_event_set(sensor_event_states,
1876 i, IPMI_DEASSERTION);
1877 display_pad_out("%d", val != 0);
1878 }
1879 }
1880 display_pad_out("\n");
1881 }
1882
1883 display_pad_refresh();
1884 }
1885
1886 static void
read_sensor(ipmi_sensor_t * sensor,int err,enum ipmi_value_present_e value_present,unsigned int raw_val,double val,ipmi_states_t * states,void * cb_data)1887 read_sensor(ipmi_sensor_t *sensor,
1888 int err,
1889 enum ipmi_value_present_e value_present,
1890 unsigned int raw_val,
1891 double val,
1892 ipmi_states_t *states,
1893 void *cb_data)
1894 {
1895 ipmi_sensor_id_t sensor_id;
1896 enum ipmi_thresh_e t;
1897
1898 if (err) {
1899 if (sensor_displayed) {
1900 wmove(display_pad, value_pos.y, value_pos.x);
1901 display_pad_out("unreadable: %x", err);
1902 display_pad_refresh();
1903 } else {
1904 curr_display_type = DISPLAY_NONE;
1905 }
1906 return;
1907 }
1908
1909 sensor_id = ipmi_sensor_convert_to_id(sensor);
1910 if (!((curr_display_type == DISPLAY_SENSOR)
1911 && (ipmi_cmp_sensor_id(sensor_id, curr_sensor_id) == 0)))
1912 return;
1913
1914 if (sensor_displayed) {
1915 wmove(display_pad, value_pos.y, value_pos.x);
1916 if (value_present == IPMI_BOTH_VALUES_PRESENT)
1917 display_pad_out("%f (%2.2x)", val, raw_val);
1918 else if (value_present == IPMI_RAW_VALUE_PRESENT)
1919 display_pad_out("0x%x (RAW)", raw_val);
1920 else
1921 display_pad_out("unreadable");
1922
1923 for (t=IPMI_LOWER_NON_CRITICAL; t<=IPMI_UPPER_NON_RECOVERABLE; t++) {
1924 if (threshold_positions[t].set) {
1925 wmove(display_pad,
1926 threshold_positions[t].oor.y,
1927 threshold_positions[t].oor.x);
1928 if (ipmi_is_threshold_out_of_range(states, t))
1929 display_pad_out("true ");
1930 else
1931 display_pad_out("false");
1932 }
1933 }
1934 display_pad_refresh();
1935 } else {
1936 sensor_read_err = err;
1937 sensor_value_present = value_present;
1938 sensor_raw_val = raw_val;
1939 sensor_val = val;
1940 if (states)
1941 ipmi_copy_states(sensor_states, states);
1942 display_sensor(ipmi_sensor_get_entity(sensor), sensor);
1943 }
1944 }
1945
1946
1947 static void
read_thresholds(ipmi_sensor_t * sensor,int err,ipmi_thresholds_t * th,void * cb_data)1948 read_thresholds(ipmi_sensor_t *sensor,
1949 int err,
1950 ipmi_thresholds_t *th,
1951 void *cb_data)
1952 {
1953 ipmi_sensor_id_t sensor_id;
1954 enum ipmi_thresh_e t;
1955 double val;
1956 int rv;
1957
1958 sensor_id = ipmi_sensor_convert_to_id(sensor);
1959 if (!((curr_display_type == DISPLAY_SENSOR)
1960 && (ipmi_cmp_sensor_id(sensor_id, curr_sensor_id) == 0)))
1961 return;
1962
1963 if (sensor_displayed) {
1964 if (err) {
1965 for (t=IPMI_LOWER_NON_CRITICAL; t<=IPMI_UPPER_NON_RECOVERABLE; t++)
1966 {
1967 if (threshold_positions[t].set) {
1968 wmove(display_pad,
1969 threshold_positions[t].value.y,
1970 threshold_positions[t].value.x);
1971 display_pad_out("?");
1972 }
1973 }
1974 } else {
1975 for (t=IPMI_LOWER_NON_CRITICAL; t<=IPMI_UPPER_NON_RECOVERABLE; t++) {
1976 if (threshold_positions[t].set) {
1977 rv = ipmi_threshold_get(th, t, &val);
1978 wmove(display_pad,
1979 threshold_positions[t].value.y,
1980 threshold_positions[t].value.x);
1981 if (rv)
1982 display_pad_out("?", val);
1983 else
1984 display_pad_out("%f", val);
1985 }
1986 }
1987 }
1988 display_pad_refresh();
1989 } else {
1990 sensor_read_thresh_err = err;
1991 if (th)
1992 ipmi_copy_thresholds(sensor_thresholds, th);
1993 display_sensor(ipmi_sensor_get_entity(sensor), sensor);
1994 }
1995 }
1996
1997 static void
read_thresh_event_enables(ipmi_sensor_t * sensor,int err,ipmi_event_state_t * states,void * cb_data)1998 read_thresh_event_enables(ipmi_sensor_t *sensor,
1999 int err,
2000 ipmi_event_state_t *states,
2001 void *cb_data)
2002 {
2003 ipmi_sensor_id_t sensor_id;
2004 enum ipmi_thresh_e t;
2005 int global_enable;
2006 int scanning_enable;
2007
2008 sensor_id = ipmi_sensor_convert_to_id(sensor);
2009 if (!((curr_display_type == DISPLAY_SENSOR)
2010 && (ipmi_cmp_sensor_id(sensor_id, curr_sensor_id) == 0)))
2011 return;
2012
2013 if (sensor_displayed) {
2014 if (err)
2015 return;
2016
2017 global_enable = ipmi_event_state_get_events_enabled(states);
2018 scanning_enable = ipmi_event_state_get_scanning_enabled(states);
2019 wmove(display_pad, enabled_pos.y, enabled_pos.x);
2020 if (err)
2021 display_pad_out("? ");
2022 else if (global_enable)
2023 display_pad_out("enabled");
2024 else
2025 display_pad_out("disabled");
2026
2027 wmove(display_pad, scanning_pos.y, scanning_pos.x);
2028 if (err)
2029 display_pad_out("? ");
2030 else if (scanning_enable)
2031 display_pad_out("enabled");
2032 else
2033 display_pad_out("disabled");
2034
2035 if (ipmi_sensor_get_event_support(sensor)
2036 != IPMI_EVENT_SUPPORT_PER_STATE)
2037 goto out;
2038
2039 for (t=IPMI_LOWER_NON_CRITICAL; t<=IPMI_UPPER_NON_RECOVERABLE; t++) {
2040 if (threshold_positions[t].set) {
2041 wmove(display_pad,
2042 threshold_positions[t].enabled.y,
2043 threshold_positions[t].enabled.x);
2044 if (err) {
2045 display_pad_out("? ");
2046 continue;
2047 }
2048 display_pad_out(" ");
2049 if (ipmi_is_threshold_event_set(states, t,
2050 IPMI_GOING_LOW,
2051 IPMI_ASSERTION))
2052 display_pad_out("L^");
2053 else
2054 display_pad_out(" ");
2055 if (ipmi_is_threshold_event_set(states, t,
2056 IPMI_GOING_LOW,
2057 IPMI_DEASSERTION))
2058 display_pad_out("Lv");
2059 else
2060 display_pad_out(" ");
2061 if (ipmi_is_threshold_event_set(states, t,
2062 IPMI_GOING_HIGH,
2063 IPMI_ASSERTION))
2064 display_pad_out("H^");
2065 else
2066 display_pad_out(" ");
2067 if (ipmi_is_threshold_event_set(states, t,
2068 IPMI_GOING_HIGH,
2069 IPMI_DEASSERTION))
2070 display_pad_out("HV");
2071 else
2072 display_pad_out(" ");
2073 }
2074 }
2075
2076 out:
2077 display_pad_refresh();
2078 } else {
2079 sensor_event_states_err = err;
2080 if (states)
2081 ipmi_copy_event_state(sensor_event_states, states);
2082 display_sensor(ipmi_sensor_get_entity(sensor), sensor);
2083 }
2084 }
2085
2086 static void
read_discrete_event_enables(ipmi_sensor_t * sensor,int err,ipmi_event_state_t * states,void * cb_data)2087 read_discrete_event_enables(ipmi_sensor_t *sensor,
2088 int err,
2089 ipmi_event_state_t *states,
2090 void *cb_data)
2091 {
2092 ipmi_sensor_id_t sensor_id;
2093 int i;
2094 int val;
2095 int global_enable;
2096 int scanning_enable;
2097
2098 sensor_id = ipmi_sensor_convert_to_id(sensor);
2099 if (!((curr_display_type == DISPLAY_SENSOR)
2100 && (ipmi_cmp_sensor_id(sensor_id, curr_sensor_id) == 0)))
2101 return;
2102
2103 if (sensor_displayed) {
2104 global_enable = ipmi_event_state_get_events_enabled(states);
2105 scanning_enable = ipmi_event_state_get_scanning_enabled(states);
2106
2107 wmove(display_pad, enabled_pos.y, enabled_pos.x);
2108 if (err)
2109 display_pad_out("? ");
2110 else if (global_enable)
2111 display_pad_out("enabled");
2112 else
2113 display_pad_out("disabled");
2114
2115 wmove(display_pad, scanning_pos.y, scanning_pos.x);
2116 if (err)
2117 display_pad_out("? ");
2118 else if (scanning_enable)
2119 display_pad_out("enabled");
2120 else
2121 display_pad_out("disabled");
2122
2123 if (ipmi_sensor_get_event_support(sensor)
2124 != IPMI_EVENT_SUPPORT_PER_STATE)
2125 goto out;
2126
2127 if (err) {
2128 wmove(display_pad, discr_assert_enab.y, discr_assert_enab.x);
2129 display_pad_out("?");
2130 wmove(display_pad, discr_deassert_enab.y, discr_deassert_enab.x);
2131 display_pad_out("?");
2132 } else {
2133 wmove(display_pad, discr_assert_enab.y, discr_assert_enab.x);
2134 for (i=0; i<15; i++) {
2135 val = ipmi_is_discrete_event_set(states, i, IPMI_ASSERTION);
2136 display_pad_out("%d", val != 0);
2137 }
2138 wmove(display_pad, discr_deassert_enab.y, discr_deassert_enab.x);
2139 for (i=0; i<15; i++) {
2140 val = ipmi_is_discrete_event_set(states, i, IPMI_DEASSERTION);
2141 display_pad_out("%d", val != 0);
2142 }
2143 }
2144 out:
2145 display_pad_refresh();
2146 } else {
2147 sensor_event_states_err = err;
2148 if (states)
2149 ipmi_copy_event_state(sensor_event_states, states);
2150 display_sensor(ipmi_sensor_get_entity(sensor), sensor);
2151 }
2152 }
2153
2154 static void
read_states(ipmi_sensor_t * sensor,int err,ipmi_states_t * states,void * cb_data)2155 read_states(ipmi_sensor_t *sensor,
2156 int err,
2157 ipmi_states_t *states,
2158 void *cb_data)
2159 {
2160 ipmi_sensor_id_t sensor_id;
2161 int i;
2162 int val;
2163
2164 sensor_id = ipmi_sensor_convert_to_id(sensor);
2165 if (!((curr_display_type == DISPLAY_SENSOR)
2166 && (ipmi_cmp_sensor_id(sensor_id, curr_sensor_id) == 0)))
2167 return;
2168
2169 if (sensor_displayed) {
2170 wmove(display_pad, value_pos.y, value_pos.x);
2171 if (err) {
2172 display_pad_out("?");
2173 } else {
2174 for (i=0; i<15; i++) {
2175 val = ipmi_is_state_set(states, i);
2176 display_pad_out("%d", val != 0);
2177 }
2178 }
2179 display_pad_refresh();
2180 } else {
2181 sensor_read_err = err;
2182 if (states)
2183 ipmi_copy_states(sensor_states, states);
2184 display_sensor(ipmi_sensor_get_entity(sensor), sensor);
2185 }
2186 }
2187
2188 static void
redisplay_sensor(ipmi_sensor_t * sensor,void * cb_data)2189 redisplay_sensor(ipmi_sensor_t *sensor, void *cb_data)
2190 {
2191 int rv;
2192 ipmi_entity_t *entity;
2193
2194 entity = ipmi_sensor_get_entity(sensor);
2195 if (!entity)
2196 return;
2197
2198 if (!ipmi_entity_is_present(entity)
2199 && ipmi_sensor_get_ignore_if_no_entity(sensor))
2200 {
2201 wmove(display_pad, value_pos.y, value_pos.x);
2202 display_pad_out("not present");
2203 return;
2204 }
2205
2206 if (ipmi_sensor_get_event_reading_type(sensor)
2207 == IPMI_EVENT_READING_TYPE_THRESHOLD)
2208 {
2209 rv = ipmi_sensor_get_reading(sensor, read_sensor, NULL);
2210 if (rv)
2211 ui_log("redisplay_sensor: Unable to get sensor reading: 0x%x\n",
2212 rv);
2213
2214 switch (ipmi_sensor_get_threshold_access(sensor))
2215 {
2216 case IPMI_THRESHOLD_ACCESS_SUPPORT_READABLE:
2217 case IPMI_THRESHOLD_ACCESS_SUPPORT_SETTABLE:
2218 rv = ipmi_sensor_get_thresholds(sensor, read_thresholds, NULL);
2219 if (rv)
2220 ui_log("Unable to get threshold values: 0x%x\n", rv);
2221 break;
2222
2223 default:
2224 break;
2225 }
2226
2227 switch (ipmi_sensor_get_event_support(sensor))
2228 {
2229 case IPMI_EVENT_SUPPORT_PER_STATE:
2230 case IPMI_EVENT_SUPPORT_ENTIRE_SENSOR:
2231 rv = ipmi_sensor_get_event_enables(sensor,
2232 read_thresh_event_enables,
2233 NULL);
2234 if (rv)
2235 ui_log("Unable to get event values: 0x%x\n", rv);
2236 break;
2237
2238 default:
2239 break;
2240 }
2241 } else {
2242 rv = ipmi_sensor_get_states(sensor, read_states, NULL);
2243 if (rv)
2244 ui_log("Unable to get sensor reading: 0x%x\n", rv);
2245
2246 switch (ipmi_sensor_get_event_support(sensor))
2247 {
2248 case IPMI_EVENT_SUPPORT_PER_STATE:
2249 case IPMI_EVENT_SUPPORT_ENTIRE_SENSOR:
2250 rv = ipmi_sensor_get_event_enables(sensor,
2251 read_discrete_event_enables,
2252 NULL);
2253 if (rv)
2254 ui_log("Unable to get event values: 0x%x\n", rv);
2255 break;
2256
2257 default:
2258 break;
2259 }
2260 }
2261 }
2262
2263 static void
sensor_handler(ipmi_entity_t * entity,ipmi_sensor_t * sensor,void * cb_data)2264 sensor_handler(ipmi_entity_t *entity, ipmi_sensor_t *sensor, void *cb_data)
2265 {
2266 char name[33];
2267 struct sensor_info *sinfo = cb_data;
2268 int rv;
2269 int present = 1;
2270
2271 ipmi_sensor_get_id(sensor, name, 33);
2272 if (strcmp(name, sinfo->name) == 0) {
2273 sinfo->found = 1;
2274 curr_display_type = DISPLAY_SENSOR;
2275 curr_sensor_id = ipmi_sensor_convert_to_id(sensor);
2276
2277 sensor_displayed = 0;
2278 sensor_ops_to_read_count = 1;
2279 if (! ipmi_entity_is_present(entity)
2280 && ipmi_sensor_get_ignore_if_no_entity(sensor))
2281 {
2282 present = 0;
2283 }
2284 if (ipmi_sensor_get_event_reading_type(sensor)
2285 == IPMI_EVENT_READING_TYPE_THRESHOLD)
2286 {
2287 if (present) {
2288 sensor_ops_to_read_count++;
2289 rv = ipmi_sensor_get_reading(sensor, read_sensor, NULL);
2290 if (rv)
2291 ui_log("Unable to get sensor reading: 0x%x\n", rv);
2292
2293 switch (ipmi_sensor_get_threshold_access(sensor))
2294 {
2295 case IPMI_THRESHOLD_ACCESS_SUPPORT_READABLE:
2296 case IPMI_THRESHOLD_ACCESS_SUPPORT_SETTABLE:
2297 sensor_ops_to_read_count++;
2298 rv = ipmi_sensor_get_thresholds(sensor, read_thresholds,
2299 NULL);
2300 if (rv)
2301 ui_log("Unable to get threshold values: 0x%x\n", rv);
2302 break;
2303
2304 default:
2305 break;
2306 }
2307
2308 switch (ipmi_sensor_get_event_support(sensor))
2309 {
2310 case IPMI_EVENT_SUPPORT_PER_STATE:
2311 case IPMI_EVENT_SUPPORT_ENTIRE_SENSOR:
2312 sensor_ops_to_read_count++;
2313 rv = ipmi_sensor_get_event_enables
2314 (sensor,
2315 read_thresh_event_enables,
2316 NULL);
2317 if (rv)
2318 ui_log("Unable to get event values: 0x%x\n", rv);
2319 break;
2320
2321 default:
2322 break;
2323 }
2324 }
2325 } else {
2326 if (present) {
2327 sensor_ops_to_read_count++;
2328 rv = ipmi_sensor_get_states(sensor, read_states, NULL);
2329 if (rv)
2330 ui_log("Unable to get sensor reading: 0x%x\n", rv);
2331
2332 switch (ipmi_sensor_get_event_support(sensor))
2333 {
2334 case IPMI_EVENT_SUPPORT_PER_STATE:
2335 case IPMI_EVENT_SUPPORT_ENTIRE_SENSOR:
2336 sensor_ops_to_read_count++;
2337 rv = ipmi_sensor_get_event_enables
2338 (sensor,
2339 read_discrete_event_enables,
2340 NULL);
2341 if (rv)
2342 ui_log("Unable to get event values: 0x%x\n", rv);
2343 break;
2344
2345 default:
2346 break;
2347 }
2348 }
2349 }
2350 display_sensor(entity, sensor);
2351
2352 display_pad_refresh();
2353 }
2354 }
2355
2356 static void
found_entity_for_sensor(ipmi_entity_t * entity,char ** toks,char ** toks2,void * cb_data)2357 found_entity_for_sensor(ipmi_entity_t *entity,
2358 char **toks,
2359 char **toks2,
2360 void *cb_data)
2361 {
2362 struct sensor_info sinfo;
2363
2364 sinfo.name = strtok_r(NULL, "", toks2);
2365 if (!sinfo.name) {
2366 cmd_win_out("Invalid sensor given\n");
2367 return;
2368 }
2369 conv_to_spaces(sinfo.name);
2370 sinfo.found = 0;
2371
2372 ipmi_entity_iterate_sensors(entity, sensor_handler, &sinfo);
2373 if (!sinfo.found) {
2374 char loc[MAX_ENTITY_LOC_SIZE];
2375
2376 conv_from_spaces(sinfo.name);
2377 cmd_win_out("Sensor %s.%s not found\n",
2378 get_entity_loc(entity, loc, sizeof(loc)),
2379 sinfo.name);
2380 return;
2381 }
2382 }
2383
2384 int
sensor_cmd(char * cmd,char ** toks,void * cb_data)2385 sensor_cmd(char *cmd, char **toks, void *cb_data)
2386 {
2387 entity_finder(cmd, toks, found_entity_for_sensor, NULL);
2388 return 0;
2389 }
2390
2391 typedef struct events_enable_info_s
2392 {
2393 ipmi_event_state_t *states;
2394 } events_enable_info_t;
2395
2396 void
events_enable_done(ipmi_sensor_t * sensor,int err,void * cb_data)2397 events_enable_done(ipmi_sensor_t *sensor,
2398 int err,
2399 void *cb_data)
2400 {
2401 if (err)
2402 ui_log("Error setting events enable: 0x%x", err);
2403 }
2404
2405 static void
events_enable(ipmi_sensor_t * sensor,void * cb_data)2406 events_enable(ipmi_sensor_t *sensor, void *cb_data)
2407 {
2408 events_enable_info_t *info = cb_data;
2409 int rv;
2410
2411 rv = ipmi_sensor_set_event_enables(sensor, info->states,
2412 events_enable_done, NULL);
2413 if (rv)
2414 ui_log("Error sending events enable: 0x%x", rv);
2415 ipmi_mem_free(info);
2416 }
2417
2418 static int
events_enable_cmd(char * cmd,char ** toks,void * cb_data)2419 events_enable_cmd(char *cmd, char **toks, void *cb_data)
2420 {
2421 events_enable_info_t *info;
2422 unsigned char enable;
2423 int i;
2424 char *enptr;
2425 int rv;
2426
2427 info = ipmi_mem_alloc(sizeof(*info));
2428 if (!info) {
2429 cmd_win_out("Out of memory\n");
2430 return 0;
2431 }
2432
2433 info->states = ipmi_mem_alloc(ipmi_event_state_size());
2434 if (!info->states) {
2435 ipmi_mem_free(info);
2436 cmd_win_out("Out of memory\n");
2437 return 0;
2438 }
2439
2440 ipmi_event_state_init(info->states);
2441
2442 if (get_uchar(toks, &enable, "events"))
2443 return 0;
2444 ipmi_event_state_set_events_enabled(info->states, enable);
2445
2446 if (get_uchar(toks, &enable, "scanning"))
2447 return 0;
2448 ipmi_event_state_set_scanning_enabled(info->states, enable);
2449
2450 enptr = strtok_r(NULL, " \t\n", toks);
2451 if (!enptr) {
2452 cmd_win_out("No assertion mask given\n");
2453 return 0;
2454 }
2455 for (i=0; enptr[i]!='\0'; i++) {
2456 if (enptr[i] == '1')
2457 ipmi_discrete_event_set(info->states, i, IPMI_ASSERTION);
2458 else if (enptr[i] == '0')
2459 ipmi_discrete_event_clear(info->states, i, IPMI_ASSERTION);
2460 else {
2461 cmd_win_out("Invalid assertion value\n");
2462 return 0;
2463 }
2464 }
2465
2466 enptr = strtok_r(NULL, " \t\n", toks);
2467 if (!enptr) {
2468 cmd_win_out("No deassertion mask given\n");
2469 return 0;
2470 }
2471 for (i=0; enptr[i]!='\0'; i++) {
2472 if (enptr[i] == '1')
2473 ipmi_discrete_event_set(info->states, i, IPMI_DEASSERTION);
2474 else if (enptr[i] == '0')
2475 ipmi_discrete_event_clear(info->states, i, IPMI_DEASSERTION);
2476 else {
2477 cmd_win_out("Invalid deassertion value\n");
2478 return 0;
2479 }
2480 }
2481
2482 rv = ipmi_sensor_pointer_cb(curr_sensor_id, events_enable, info);
2483 if (rv) {
2484 cmd_win_out("Unable to get sensor pointer: 0x%x\n", rv);
2485 ipmi_mem_free(info);
2486 }
2487 return 0;
2488 }
2489
2490 static void
controls_handler(ipmi_entity_t * entity,ipmi_control_t * control,void * cb_data)2491 controls_handler(ipmi_entity_t *entity, ipmi_control_t *control, void *cb_data)
2492 {
2493 char loc[MAX_ENTITY_LOC_SIZE];
2494 char name[33];
2495 char name2[33];
2496
2497 ipmi_control_get_id(control, name, 33);
2498 strcpy(name2, name);
2499 conv_from_spaces(name2);
2500 display_pad_out(" %s.%s - %s\n",
2501 get_entity_loc(entity, loc, sizeof(loc)),
2502 name2, name);
2503 }
2504
2505 static void
found_entity_for_controls(ipmi_entity_t * entity,char ** toks,char ** toks2,void * cb_data)2506 found_entity_for_controls(ipmi_entity_t *entity,
2507 char **toks,
2508 char **toks2,
2509 void *cb_data)
2510 {
2511 char loc[MAX_ENTITY_LOC_SIZE];
2512
2513 curr_display_type = DISPLAY_CONTROLS;
2514 display_pad_clear();
2515 display_pad_out("Controls for entity %s:\n",
2516 get_entity_loc(entity, loc, sizeof(loc)));
2517 ipmi_entity_iterate_controls(entity, controls_handler, NULL);
2518 display_pad_refresh();
2519 }
2520
2521 static int
controls_cmd(char * cmd,char ** toks,void * cb_data)2522 controls_cmd(char *cmd, char **toks, void *cb_data)
2523 {
2524 entity_finder(cmd, toks, found_entity_for_controls, NULL);
2525 return 0;
2526 }
2527
2528 int control_displayed;
2529 int control_ops_to_read_count;
2530 int control_read_err;
2531 int *normal_control_vals;
2532 ipmi_light_setting_t *light_control_val;
2533 int id_control_length;
2534 unsigned char *id_control_vals;
2535
2536 static void
display_control(ipmi_entity_t * entity,ipmi_control_t * control)2537 display_control(ipmi_entity_t *entity, ipmi_control_t *control)
2538 {
2539 char loc[MAX_ENTITY_LOC_SIZE];
2540 int control_type;
2541 char name[33];
2542 char cname[IPMI_CONTROL_NAME_LEN];
2543 int i;
2544 int num_vals;
2545
2546 if (control_displayed)
2547 return;
2548
2549 control_ops_to_read_count--;
2550 if (control_ops_to_read_count > 0)
2551 return;
2552
2553 control_displayed = 1;
2554
2555 ipmi_control_get_id(control, name, 33);
2556 curr_control_id = ipmi_control_convert_to_id(control);
2557
2558 display_pad_clear();
2559
2560 conv_from_spaces(name);
2561 display_pad_out("Control %s.%s:\n",
2562 get_entity_loc(entity, loc, sizeof(loc)),
2563 name);
2564 if (ipmi_control_get_ignore_if_no_entity(control))
2565 display_pad_out(" ignore if entity not present\n");
2566 else
2567 display_pad_out(" still there if entity not present\n");
2568 ipmi_control_get_name(control, cname, sizeof(cname));
2569 display_pad_out(" name = %s\n", cname);
2570 control_type = ipmi_control_get_type(control);
2571 display_pad_out(" type = %s (%d)\n",
2572 ipmi_control_get_type_string(control), control_type);
2573 num_vals = ipmi_control_get_num_vals(control);
2574 switch (control_type) {
2575 case IPMI_CONTROL_LIGHT:
2576 case IPMI_CONTROL_RELAY:
2577 case IPMI_CONTROL_ALARM:
2578 case IPMI_CONTROL_RESET:
2579 case IPMI_CONTROL_ONE_SHOT_RESET:
2580 case IPMI_CONTROL_POWER:
2581 case IPMI_CONTROL_FAN_SPEED:
2582 case IPMI_CONTROL_OUTPUT:
2583 case IPMI_CONTROL_ONE_SHOT_OUTPUT:
2584 display_pad_out(" num entities = %d\n", num_vals);
2585 break;
2586
2587 case IPMI_CONTROL_DISPLAY:
2588 case IPMI_CONTROL_IDENTIFIER:
2589 break;
2590 }
2591 display_pad_out(" value = ");
2592 getyx(display_pad, value_pos.y, value_pos.x);
2593
2594 if (! ipmi_control_is_readable(control)) {
2595 display_pad_out("not readable");
2596 } else if (control_read_err) {
2597 /* Nothing to do. */
2598 } else {
2599 switch (control_type) {
2600 case IPMI_CONTROL_LIGHT:
2601 if (ipmi_control_light_set_with_setting(control)) {
2602 if (light_control_val) {
2603 ipmi_light_setting_t *setting = light_control_val;
2604 for (i=0; i<num_vals; ) {
2605 int color, on, off, lc;
2606 ipmi_light_setting_get_color(setting, i, &color);
2607 ipmi_light_setting_get_on_time(setting, i, &on);
2608 ipmi_light_setting_get_off_time(setting, i, &off);
2609 ipmi_light_setting_in_local_control(setting, i,
2610 &lc);
2611 wmove(display_pad, value_pos.y+i, value_pos.x);
2612 display_pad_out("0x%x 0x%x 0x%x %s",
2613 color, on, off,
2614 lc ? "local cnt": " ");
2615 i++;
2616 if (i < num_vals)
2617 display_pad_out("\n ");
2618 }
2619 ipmi_free_light_settings(light_control_val);
2620 light_control_val = NULL;
2621 } else {
2622 display_pad_out("error reading values");
2623 }
2624 break;
2625 }
2626 /* FALLTHRU */
2627
2628 case IPMI_CONTROL_RELAY:
2629 case IPMI_CONTROL_ALARM:
2630 case IPMI_CONTROL_RESET:
2631 case IPMI_CONTROL_ONE_SHOT_RESET:
2632 case IPMI_CONTROL_POWER:
2633 case IPMI_CONTROL_FAN_SPEED:
2634 case IPMI_CONTROL_OUTPUT:
2635 case IPMI_CONTROL_ONE_SHOT_OUTPUT:
2636 if (normal_control_vals) {
2637 for (i=0; i<num_vals; ) {
2638 display_pad_out("%d (0x%x)", normal_control_vals[i],
2639 normal_control_vals[i]);
2640 i++;
2641 if (i < num_vals)
2642 display_pad_out("\n ");
2643 }
2644 ipmi_mem_free(normal_control_vals);
2645 normal_control_vals = NULL;
2646 } else {
2647 display_pad_out("error reading values");
2648 }
2649 break;
2650
2651 case IPMI_CONTROL_DISPLAY:
2652 break;
2653
2654 case IPMI_CONTROL_IDENTIFIER:
2655 if (id_control_vals) {
2656 for (i=0; i<id_control_length;) {
2657 display_pad_out("0x%2.2x\n", id_control_vals[i]);
2658 i++;
2659 if (i < num_vals)
2660 display_pad_out("\n ");
2661 }
2662 ipmi_mem_free(id_control_vals);
2663 id_control_vals = NULL;
2664 } else {
2665 display_pad_out("error reading values");
2666 }
2667 break;
2668 }
2669 }
2670 display_pad_out("\n");
2671
2672 display_pad_refresh();
2673 }
2674
2675 static void
light_control_val_read(ipmi_control_t * control,int err,ipmi_light_setting_t * setting,void * cb_data)2676 light_control_val_read(ipmi_control_t *control,
2677 int err,
2678 ipmi_light_setting_t *setting,
2679 void *cb_data)
2680 {
2681 ipmi_control_id_t control_id;
2682 int num_vals;
2683 int i;
2684
2685 if (control == NULL) {
2686 /* The control went away, stop the operation. */
2687 wmove(display_pad, value_pos.y, value_pos.x);
2688 display_pad_out("invalid");
2689 curr_display_type = DISPLAY_NONE;
2690 return;
2691 }
2692 control_id = ipmi_control_convert_to_id(control);
2693 if (!((curr_display_type == DISPLAY_CONTROL)
2694 && (ipmi_cmp_control_id(control_id, curr_control_id) == 0)))
2695 return;
2696
2697 num_vals = ipmi_control_get_num_vals(control);
2698
2699 if (control_displayed) {
2700 if (err) {
2701 wmove(display_pad, value_pos.y, value_pos.x);
2702 display_pad_out("?");
2703 } else {
2704 for (i=0; i<num_vals; i++) {
2705 int color, on, off, lc;
2706 ipmi_light_setting_get_color(setting, i, &color);
2707 ipmi_light_setting_get_on_time(setting, i, &on);
2708 ipmi_light_setting_get_off_time(setting, i, &off);
2709 ipmi_light_setting_in_local_control(setting, i, &lc);
2710 wmove(display_pad, value_pos.y+i, value_pos.x);
2711 display_pad_out("0x%x 0x%x 0x%x %s",
2712 color, on, off,
2713 lc ? "local cnt": " ");
2714 }
2715 }
2716 display_pad_refresh();
2717 } else {
2718 if (light_control_val)
2719 ipmi_free_light_settings(light_control_val);
2720 if (err) {
2721 light_control_val = NULL;
2722 } else {
2723 light_control_val = ipmi_light_settings_dup(setting);
2724 }
2725 display_control(ipmi_control_get_entity(control), control);
2726 }
2727 }
2728
2729 static void
normal_control_val_read(ipmi_control_t * control,int err,int * val,void * cb_data)2730 normal_control_val_read(ipmi_control_t *control,
2731 int err,
2732 int *val,
2733 void *cb_data)
2734 {
2735 ipmi_control_id_t control_id;
2736 int num_vals;
2737 int i;
2738
2739 if (control == NULL) {
2740 /* The control went away, stop the operation. */
2741 wmove(display_pad, value_pos.y, value_pos.x);
2742 display_pad_out("invalid");
2743 curr_display_type = DISPLAY_NONE;
2744 return;
2745 }
2746 control_id = ipmi_control_convert_to_id(control);
2747 if (!((curr_display_type == DISPLAY_CONTROL)
2748 && (ipmi_cmp_control_id(control_id, curr_control_id) == 0)))
2749 return;
2750
2751 num_vals = ipmi_control_get_num_vals(control);
2752
2753 if (control_displayed) {
2754 if (err) {
2755 wmove(display_pad, value_pos.y, value_pos.x);
2756 display_pad_out("?");
2757 } else {
2758 for (i=0; i<num_vals; i++) {
2759 wmove(display_pad, value_pos.y+i, value_pos.x);
2760 display_pad_out("%d (0x%x)", val[i], val[i]);
2761 }
2762 }
2763 display_pad_refresh();
2764 } else {
2765 if (err) {
2766 if (normal_control_vals)
2767 ipmi_mem_free(normal_control_vals);
2768 normal_control_vals = NULL;
2769 } else {
2770 normal_control_vals = ipmi_mem_alloc(sizeof(int) * num_vals);
2771 if (normal_control_vals) {
2772 memcpy(normal_control_vals, val, sizeof(int) * num_vals);
2773 }
2774 }
2775 display_control(ipmi_control_get_entity(control), control);
2776 }
2777 }
2778
2779 static void
identifier_control_val_read(ipmi_control_t * control,int err,unsigned char * val,int length,void * cb_data)2780 identifier_control_val_read(ipmi_control_t *control,
2781 int err,
2782 unsigned char *val,
2783 int length,
2784 void *cb_data)
2785 {
2786 ipmi_control_id_t control_id;
2787 int i;
2788
2789 if (control == NULL) {
2790 /* The control went away, stop the operation. */
2791 wmove(display_pad, value_pos.y, value_pos.x);
2792 display_pad_out("invalid");
2793 curr_display_type = DISPLAY_NONE;
2794 return;
2795 }
2796
2797 control_id = ipmi_control_convert_to_id(control);
2798 if (!((curr_display_type == DISPLAY_CONTROL)
2799 && (ipmi_cmp_control_id(control_id, curr_control_id) == 0)))
2800 return;
2801
2802 if (control_displayed) {
2803 if (err) {
2804 wmove(display_pad, value_pos.y, value_pos.x);
2805 display_pad_out("?");
2806 } else {
2807 wmove(display_pad, value_pos.y, value_pos.x);
2808 for (i=0; i<length; i++) {
2809 display_pad_out("0x%2.2x", val[i]);
2810 if (i < length)
2811 display_pad_out("\n ");
2812 }
2813 }
2814 display_pad_refresh();
2815 } else {
2816 if (err) {
2817 if (id_control_vals)
2818 ipmi_mem_free(id_control_vals);
2819 id_control_vals = NULL;
2820 } else {
2821 id_control_length = length;
2822 id_control_vals = ipmi_mem_alloc(sizeof(unsigned char) * length);
2823 if (id_control_vals) {
2824 memcpy(id_control_vals, val, sizeof(unsigned char) * length);
2825 }
2826 display_control(ipmi_control_get_entity(control), control);
2827 }
2828 }
2829 }
2830
2831 static void
redisplay_control(ipmi_control_t * control,void * cb_data)2832 redisplay_control(ipmi_control_t *control, void *cb_data)
2833 {
2834 int control_type;
2835 ipmi_entity_t *entity;
2836
2837 entity = ipmi_control_get_entity(control);
2838 if (!entity)
2839 return;
2840
2841 if (! ipmi_control_is_readable(control)) {
2842 wmove(display_pad, value_pos.y, value_pos.x);
2843 display_pad_out("not readable");
2844 display_pad_refresh();
2845 return;
2846 }
2847
2848 if (!ipmi_entity_is_present(entity)
2849 && ipmi_control_get_ignore_if_no_entity(control))
2850 {
2851 wmove(display_pad, value_pos.y, value_pos.x);
2852 display_pad_out("not present");
2853 display_pad_refresh();
2854 return;
2855 }
2856
2857 control_type = ipmi_control_get_type(control);
2858 switch (control_type) {
2859 case IPMI_CONTROL_LIGHT:
2860 if (ipmi_control_light_set_with_setting(control)) {
2861 ipmi_control_get_light(control, light_control_val_read, NULL);
2862 break;
2863 }
2864 /* FALLTHRU */
2865 case IPMI_CONTROL_RELAY:
2866 case IPMI_CONTROL_ALARM:
2867 case IPMI_CONTROL_RESET:
2868 case IPMI_CONTROL_ONE_SHOT_RESET:
2869 case IPMI_CONTROL_POWER:
2870 case IPMI_CONTROL_FAN_SPEED:
2871 case IPMI_CONTROL_OUTPUT:
2872 case IPMI_CONTROL_ONE_SHOT_OUTPUT:
2873 ipmi_control_get_val(control, normal_control_val_read, NULL);
2874 break;
2875
2876 case IPMI_CONTROL_DISPLAY:
2877 break;
2878
2879 case IPMI_CONTROL_IDENTIFIER:
2880 ipmi_control_identifier_get_val(control,
2881 identifier_control_val_read,
2882 NULL);
2883 break;
2884 }
2885 }
2886
2887 struct control_info {
2888 int found;
2889 char *name;
2890 };
2891
2892 static void
control_handler(ipmi_entity_t * entity,ipmi_control_t * control,void * cb_data)2893 control_handler(ipmi_entity_t *entity, ipmi_control_t *control, void *cb_data)
2894 {
2895 struct control_info *iinfo = cb_data;
2896 char name[33];
2897 int control_type;
2898 int rv;
2899
2900
2901 ipmi_control_get_id(control, name, 33);
2902 if (strcmp(name, iinfo->name) == 0) {
2903 iinfo->found = 1;
2904 curr_display_type = DISPLAY_CONTROL;
2905
2906 curr_control_id = ipmi_control_convert_to_id(control);
2907
2908 control_ops_to_read_count = 1;
2909
2910 control_displayed = 0;
2911
2912 if (! ipmi_control_is_readable(control)) {
2913 /* If the control can't be read, then just display it now. */
2914 display_control(entity, control);
2915 return;
2916 }
2917
2918 control_type = ipmi_control_get_type(control);
2919 switch (control_type) {
2920 case IPMI_CONTROL_LIGHT:
2921 if (ipmi_control_light_set_with_setting(control)) {
2922 control_ops_to_read_count++;
2923 rv = ipmi_control_get_light(control, light_control_val_read,
2924 NULL);
2925 if (rv) {
2926 ui_log("Unable to read light control val: 0x%x\n", rv);
2927 }
2928 break;
2929 }
2930 /* FALLTHRU */
2931 case IPMI_CONTROL_RELAY:
2932 case IPMI_CONTROL_ALARM:
2933 case IPMI_CONTROL_RESET:
2934 case IPMI_CONTROL_ONE_SHOT_RESET:
2935 case IPMI_CONTROL_POWER:
2936 case IPMI_CONTROL_FAN_SPEED:
2937 case IPMI_CONTROL_OUTPUT:
2938 case IPMI_CONTROL_ONE_SHOT_OUTPUT:
2939 control_ops_to_read_count++;
2940 rv = ipmi_control_get_val(control, normal_control_val_read, NULL);
2941 if (rv) {
2942 ui_log("Unable to read control val: 0x%x\n", rv);
2943 }
2944 break;
2945
2946 case IPMI_CONTROL_DISPLAY:
2947 break;
2948
2949 case IPMI_CONTROL_IDENTIFIER:
2950 control_ops_to_read_count++;
2951 rv = ipmi_control_identifier_get_val(control,
2952 identifier_control_val_read,
2953 NULL);
2954 if (rv) {
2955 ui_log("Unable to read control val: 0x%x\n", rv);
2956 }
2957 break;
2958 }
2959
2960 display_control(entity, control);
2961 }
2962 }
2963
2964 static void
found_entity_for_control(ipmi_entity_t * entity,char ** toks,char ** toks2,void * cb_data)2965 found_entity_for_control(ipmi_entity_t *entity,
2966 char **toks,
2967 char **toks2,
2968 void *cb_data)
2969 {
2970 struct control_info iinfo;
2971
2972 iinfo.name = strtok_r(NULL, "", toks2);
2973 if (!iinfo.name) {
2974 cmd_win_out("Invalid control given\n");
2975 return;
2976 }
2977 conv_to_spaces(iinfo.name);
2978 iinfo.found = 0;
2979
2980 ipmi_entity_iterate_controls(entity, control_handler, &iinfo);
2981 if (!iinfo.found) {
2982 char loc[MAX_ENTITY_LOC_SIZE];
2983
2984 conv_from_spaces(iinfo.name);
2985 cmd_win_out("Control %s.%s not found\n",
2986 get_entity_loc(entity, loc, sizeof(loc)),
2987 iinfo.name);
2988 return;
2989 }
2990 }
2991
2992 int
control_cmd(char * cmd,char ** toks,void * cb_data)2993 control_cmd(char *cmd, char **toks, void *cb_data)
2994 {
2995 entity_finder(cmd, toks, found_entity_for_control, NULL);
2996 return 0;
2997 }
2998
2999 typedef struct rearm_info_s
3000 {
3001 int global;
3002 ipmi_event_state_t *states;
3003 } rearm_info_t;
3004
3005 void
rearm_done(ipmi_sensor_t * sensor,int err,void * cb_data)3006 rearm_done(ipmi_sensor_t *sensor,
3007 int err,
3008 void *cb_data)
3009 {
3010 if (err)
3011 ui_log("Error rearming sensor: 0x%x", err);
3012 }
3013
3014 static void
rearm(ipmi_sensor_t * sensor,void * cb_data)3015 rearm(ipmi_sensor_t *sensor, void *cb_data)
3016 {
3017 rearm_info_t *info = cb_data;
3018 int rv;
3019
3020 rv = ipmi_sensor_rearm(sensor, info->global, info->states,
3021 rearm_done, NULL);
3022 if (rv)
3023 ui_log("Error sending rearm: 0x%x", rv);
3024 if (info->states)
3025 ipmi_mem_free(info->states);
3026 ipmi_mem_free(info);
3027 }
3028
3029 static int
rearm_cmd(char * cmd,char ** toks,void * cb_data)3030 rearm_cmd(char *cmd, char **toks, void *cb_data)
3031 {
3032 rearm_info_t *info;
3033 unsigned char global;
3034 int i;
3035 char *enptr;
3036 int rv;
3037
3038 info = ipmi_mem_alloc(sizeof(*info));
3039 if (!info) {
3040 cmd_win_out("Out of memory\n");
3041 return 0;
3042 }
3043
3044 info->states = NULL;
3045
3046 if (get_uchar(toks, &global, "global rearm"))
3047 goto out_err;
3048 info->global = global;
3049
3050 if (!global) {
3051 info->states = ipmi_mem_alloc(ipmi_event_state_size());
3052 if (!info->states) {
3053 ipmi_mem_free(info);
3054 cmd_win_out("Out of memory\n");
3055 goto out_err;
3056 }
3057
3058 ipmi_event_state_init(info->states);
3059
3060 enptr = strtok_r(NULL, " \t\n", toks);
3061 if (!enptr) {
3062 cmd_win_out("No assertion mask given\n");
3063 goto out_err;
3064 }
3065 for (i=0; enptr[i]!='\0'; i++) {
3066 if (enptr[i] == '1')
3067 ipmi_discrete_event_set(info->states, i, IPMI_ASSERTION);
3068 else if (enptr[i] == '0')
3069 ipmi_discrete_event_clear(info->states, i, IPMI_ASSERTION);
3070 else {
3071 cmd_win_out("Invalid assertion value\n");
3072 goto out_err;
3073 }
3074 }
3075
3076 enptr = strtok_r(NULL, " \t\n", toks);
3077 if (!enptr) {
3078 cmd_win_out("No deassertion mask given\n");
3079 return 0;
3080 }
3081 for (i=0; enptr[i]!='\0'; i++) {
3082 if (enptr[i] == '1')
3083 ipmi_discrete_event_set(info->states, i, IPMI_DEASSERTION);
3084 else if (enptr[i] == '0')
3085 ipmi_discrete_event_clear(info->states, i, IPMI_DEASSERTION);
3086 else {
3087 cmd_win_out("Invalid deassertion value\n");
3088 goto out_err;
3089 }
3090 }
3091 }
3092
3093 rv = ipmi_sensor_pointer_cb(curr_sensor_id, rearm, info);
3094 if (rv) {
3095 cmd_win_out("Unable to get sensor pointer: 0x%x\n", rv);
3096 goto out_err;
3097 }
3098 return 0;
3099
3100 out_err:
3101 if (info) {
3102 if (info->states)
3103 ipmi_mem_free(info->states);
3104 ipmi_mem_free(info);
3105 }
3106 return 0;
3107 }
3108
3109 void
set_hysteresis_done(ipmi_sensor_t * sensor,int err,void * cb_data)3110 set_hysteresis_done(ipmi_sensor_t *sensor,
3111 int err,
3112 void *cb_data)
3113 {
3114 if (err)
3115 ui_log("Error setting hysteresis: 0x%x", err);
3116 else
3117 ui_log("Hysteresis set");
3118 }
3119
3120 static int
set_hysteresis_cmd(char * cmd,char ** toks,void * cb_data)3121 set_hysteresis_cmd(char *cmd, char **toks, void *cb_data)
3122 {
3123 unsigned char physt, nhyst;
3124 int rv;
3125
3126 if (get_uchar(toks, &physt, "positive hysteresis value"))
3127 goto out_err;
3128
3129 if (get_uchar(toks, &nhyst, "negative hysteresis value"))
3130 goto out_err;
3131
3132 rv = ipmi_sensor_id_set_hysteresis(curr_sensor_id, physt, nhyst,
3133 set_hysteresis_done, NULL);
3134 if (rv) {
3135 cmd_win_out("Unable to set hysteresis: 0x%x\n", rv);
3136 goto out_err;
3137 }
3138
3139 out_err:
3140 return 0;
3141 }
3142
3143 void
get_hysteresis_done(ipmi_sensor_t * sensor,int err,unsigned int positive_hysteresis,unsigned int negative_hysteresis,void * cb_data)3144 get_hysteresis_done(ipmi_sensor_t *sensor,
3145 int err,
3146 unsigned int positive_hysteresis,
3147 unsigned int negative_hysteresis,
3148 void *cb_data)
3149 {
3150 if (err)
3151 ui_log("Error setting hysteresis: 0x%x", err);
3152 else
3153 ui_log("Hysteresis values: positive = 0x%x, negative = 0x%x",
3154 positive_hysteresis, negative_hysteresis);
3155 }
3156
3157 static int
get_hysteresis_cmd(char * cmd,char ** toks,void * cb_data)3158 get_hysteresis_cmd(char *cmd, char **toks, void *cb_data)
3159 {
3160 int rv;
3161
3162 rv = ipmi_sensor_id_get_hysteresis(curr_sensor_id,
3163 get_hysteresis_done, NULL);
3164 if (rv) {
3165 cmd_win_out("Unable to get hysteresis: 0x%x\n", rv);
3166 goto out_err;
3167 }
3168
3169 out_err:
3170 return 0;
3171 }
3172
3173 static int
dump_fru_str(ipmi_fru_t * fru,char * str,int (* glen)(ipmi_fru_t * fru,unsigned int * length),int (* gtype)(ipmi_fru_t * fru,enum ipmi_str_type_e * type),int (* gstr)(ipmi_fru_t * fru,char * str,unsigned int * strlen))3174 dump_fru_str(ipmi_fru_t *fru,
3175 char *str,
3176 int (*glen)(ipmi_fru_t *fru,
3177 unsigned int *length),
3178 int (*gtype)(ipmi_fru_t *fru,
3179 enum ipmi_str_type_e *type),
3180 int (*gstr)(ipmi_fru_t *fru,
3181 char *str,
3182 unsigned int *strlen))
3183 {
3184 enum ipmi_str_type_e type;
3185 int rv;
3186 char buf[128];
3187 unsigned int len;
3188
3189 rv = gtype(fru, &type);
3190 if (rv) {
3191 if (rv != ENOSYS)
3192 display_pad_out(" Error fetching type for %s: %x\n", str, rv);
3193 return rv;
3194 }
3195
3196 if (type == IPMI_BINARY_STR) {
3197 display_pad_out(" %s is in binary\n", str);
3198 return 0;
3199 } else if (type == IPMI_UNICODE_STR) {
3200 display_pad_out(" %s is in unicode\n", str);
3201 return 0;
3202 } else if (type != IPMI_ASCII_STR) {
3203 display_pad_out(" %s is in unknown format\n", str);
3204 return 0;
3205 }
3206
3207 len = sizeof(buf);
3208 rv = gstr(fru, buf, &len);
3209 if (rv) {
3210 display_pad_out(" Error fetching string for %s: %x\n", str, rv);
3211 return rv;
3212 }
3213
3214 display_pad_out(" %s: %s\n", str, buf);
3215 return 0;
3216 }
3217
3218 static int
dump_fru_custom_str(ipmi_fru_t * fru,char * str,int num,int (* glen)(ipmi_fru_t * fru,unsigned int num,unsigned int * length),int (* gtype)(ipmi_fru_t * fru,unsigned int num,enum ipmi_str_type_e * type),int (* gstr)(ipmi_fru_t * fru,unsigned int num,char * str,unsigned int * strlen))3219 dump_fru_custom_str(ipmi_fru_t *fru,
3220 char *str,
3221 int num,
3222 int (*glen)(ipmi_fru_t *fru,
3223 unsigned int num,
3224 unsigned int *length),
3225 int (*gtype)(ipmi_fru_t *fru,
3226 unsigned int num,
3227 enum ipmi_str_type_e *type),
3228 int (*gstr)(ipmi_fru_t *fru,
3229 unsigned int num,
3230 char *str,
3231 unsigned int *strlen))
3232 {
3233 enum ipmi_str_type_e type;
3234 int rv;
3235 char buf[128];
3236 unsigned int len;
3237
3238 rv = gtype(fru, num, &type);
3239 if (rv)
3240 return rv;
3241
3242 if (type == IPMI_BINARY_STR) {
3243 display_pad_out(" %s custom %d is in binary\n", str, num);
3244 return 0;
3245 } else if (type == IPMI_UNICODE_STR) {
3246 display_pad_out(" %s custom %d is in unicode\n", str, num);
3247 return 0;
3248 } else if (type != IPMI_ASCII_STR) {
3249 display_pad_out(" %s custom %d is in unknown format\n", str, num);
3250 return 0;
3251 }
3252
3253 len = sizeof(buf);
3254 rv = gstr(fru, num, buf, &len);
3255 if (rv) {
3256 display_pad_out(" Error fetching string for %s custom %d: %x\n",
3257 str, num, rv);
3258 return rv;
3259 }
3260
3261 display_pad_out(" %s custom %d: %s\n", str, num, buf);
3262 return 0;
3263 }
3264
3265 #define DUMP_FRU_STR(name, str) \
3266 dump_fru_str(fru, str, ipmi_fru_get_ ## name ## _len, \
3267 ipmi_fru_get_ ## name ## _type, \
3268 ipmi_fru_get_ ## name)
3269
3270 #define DUMP_FRU_CUSTOM_STR(name, str) \
3271 do { \
3272 int i, _rv; \
3273 for (i=0; ; i++) { \
3274 _rv = dump_fru_custom_str(fru, str, i, \
3275 ipmi_fru_get_ ## name ## _custom_len, \
3276 ipmi_fru_get_ ## name ## _custom_type, \
3277 ipmi_fru_get_ ## name ## _custom); \
3278 if (_rv) \
3279 break; \
3280 } \
3281 } while (0)
3282
3283 static int
traverse_fru_multi_record_tree(ipmi_fru_node_t * node,int indent)3284 traverse_fru_multi_record_tree(ipmi_fru_node_t *node,
3285 int indent)
3286 {
3287 const char *name;
3288 unsigned int i, k;
3289 enum ipmi_fru_data_type_e dtype;
3290 int intval, rv;
3291 double floatval;
3292 time_t time;
3293 char *data;
3294 unsigned int data_len;
3295 ipmi_fru_node_t *sub_node;
3296
3297 for (i=0; ; i++) {
3298 rv = ipmi_fru_node_get_field(node, i, &name, &dtype, &intval, &time,
3299 &floatval, &data, &data_len, &sub_node);
3300 if ((rv == EINVAL) || (rv == ENOSYS))
3301 break;
3302 else if (rv)
3303 continue;
3304
3305 if (name)
3306 display_pad_out("%*sName: %s \n", indent, "", name);
3307 else
3308 /* An array index. */
3309 display_pad_out("%*%d: \n", indent, "", i);
3310 switch (dtype) {
3311 case IPMI_FRU_DATA_INT:
3312 display_pad_out("%*sType: integer\n", indent, "");
3313 display_pad_out("%*sData: %d\n", indent, "", intval);
3314 break;
3315
3316 case IPMI_FRU_DATA_TIME:
3317 display_pad_out("%*sType: time\n", indent, "");
3318 display_pad_out("%*sData: %ld\n", indent, "", (long)time);
3319 break;
3320
3321 case IPMI_FRU_DATA_BOOLEAN:
3322 display_pad_out("%*sType: boolean\n", indent, "");
3323 display_pad_out("%*sData: %ls\n", indent, "",
3324 intval ? "true" : "false");
3325 break;
3326
3327 case IPMI_FRU_DATA_FLOAT:
3328 display_pad_out("%*sType: float\n", indent, "");
3329 display_pad_out("%*sData: %lf\n", indent, "", floatval);
3330 break;
3331
3332 case IPMI_FRU_DATA_BINARY:
3333 display_pad_out("%*sType: binary\n", indent, "");
3334 display_pad_out("%*sData:", indent, "");
3335 for(k=0; k<data_len; k++)
3336 display_pad_out(" %2.2x", data[k]);
3337 display_pad_out("\n");
3338 break;
3339
3340 case IPMI_FRU_DATA_ASCII:
3341 display_pad_out("%*sType: ascii\n", indent, "");
3342 display_pad_out("%*sData: %s\n", indent, "", data);
3343 break;
3344
3345 case IPMI_FRU_DATA_UNICODE:
3346 display_pad_out("%*sType: unicode\n", indent, "");
3347 display_pad_out("%*sData:", indent, "");
3348 for (k=0; k<data_len; k++)
3349 display_pad_out(" %2.2x", data[k]);
3350 display_pad_out("\n");
3351 break;
3352
3353 case IPMI_FRU_DATA_SUB_NODE:
3354 if (intval == -1)
3355 display_pad_out("%*sType: Record\n", indent, "");
3356 else
3357 display_pad_out("%*sType: Array\n", indent, "");
3358 traverse_fru_multi_record_tree(sub_node, indent+2);
3359 break;
3360
3361 default:
3362 display_pad_out("Type: unknown\n");
3363 break;
3364 }
3365 }
3366
3367 ipmi_fru_put_node(node);
3368
3369 return 0;
3370 }
3371
3372 static void
dump_fru_info(ipmi_fru_t * fru)3373 dump_fru_info(ipmi_fru_t *fru)
3374 {
3375 unsigned char ucval;
3376 unsigned int uival;
3377 time_t tval;
3378 int rv;
3379 int i, num_multi;
3380
3381 rv = ipmi_fru_get_internal_use_version(fru, &ucval);
3382 if (!rv)
3383 display_pad_out(" internal area version: 0x%2.2x\n", ucval);
3384
3385 rv = ipmi_fru_get_internal_use_length(fru, &uival);
3386 if (!rv)
3387 display_pad_out(" internal area length: %d\n", uival);
3388
3389 /* FIXME - dump internal use data. */
3390
3391 rv = ipmi_fru_get_chassis_info_version(fru, &ucval);
3392 if (!rv)
3393 display_pad_out(" chassis info version: 0x%2.2x\n", ucval);
3394
3395 rv = ipmi_fru_get_chassis_info_type(fru, &ucval);
3396 if (!rv)
3397 display_pad_out(" chassis info type: 0x%2.2x\n", ucval);
3398
3399 DUMP_FRU_STR(chassis_info_part_number, "chassis info part number");
3400 DUMP_FRU_STR(chassis_info_serial_number, "chassis info serial number");
3401 DUMP_FRU_CUSTOM_STR(chassis_info, "chassis info");
3402
3403 rv = ipmi_fru_get_board_info_version(fru, &ucval);
3404 if (!rv)
3405 display_pad_out(" board info version: 0x%2.2x\n", ucval);
3406
3407 rv = ipmi_fru_get_board_info_lang_code(fru, &ucval);
3408 if (!rv)
3409 display_pad_out(" board info lang code: 0x%2.2x\n", ucval);
3410
3411 rv = ipmi_fru_get_board_info_mfg_time(fru, &tval);
3412 if (!rv)
3413 display_pad_out(" board info mfg time: %ld\n", (long) tval);
3414
3415 DUMP_FRU_STR(board_info_board_manufacturer,
3416 "board info board manufacturer");
3417 DUMP_FRU_STR(board_info_board_product_name,
3418 "board info board product name");
3419 DUMP_FRU_STR(board_info_board_serial_number,
3420 "board info board serial number");
3421 DUMP_FRU_STR(board_info_board_part_number,
3422 "board info board part number");
3423 DUMP_FRU_STR(board_info_fru_file_id, "board info fru file id");
3424 DUMP_FRU_CUSTOM_STR(board_info, "board info");
3425
3426 rv = ipmi_fru_get_product_info_version(fru, &ucval);
3427 if (!rv)
3428 display_pad_out(" product info version: 0x%2.2x\n", ucval);
3429
3430 rv = ipmi_fru_get_product_info_lang_code(fru, &ucval);
3431 if (!rv)
3432 display_pad_out(" product info lang code: 0x%2.2x\n", ucval);
3433
3434 DUMP_FRU_STR(product_info_manufacturer_name,
3435 "product info manufacturer name");
3436 DUMP_FRU_STR(product_info_product_name, "product info product name");
3437 DUMP_FRU_STR(product_info_product_part_model_number,
3438 "product info product part model number");
3439 DUMP_FRU_STR(product_info_product_version, "product info product version");
3440 DUMP_FRU_STR(product_info_product_serial_number,
3441 "product info product serial number");
3442 DUMP_FRU_STR(product_info_asset_tag, "product info asset tag");
3443 DUMP_FRU_STR(product_info_fru_file_id, "product info fru file id");
3444 DUMP_FRU_CUSTOM_STR(product_info, "product info");
3445 num_multi = ipmi_fru_get_num_multi_records(fru);
3446 for (i=0; i<num_multi; i++) {
3447 unsigned char type, ver;
3448 unsigned int j;
3449 unsigned int len;
3450 unsigned char *data;
3451 ipmi_fru_node_t *node;
3452 const char *name;
3453
3454 rv = ipmi_fru_get_multi_record_type(fru, i, &type);
3455 if (rv)
3456 display_pad_out(" multi-record %d, error getting type: %x\n", rv);
3457 rv = ipmi_fru_get_multi_record_format_version(fru, i, &ver);
3458 if (rv)
3459 display_pad_out(" multi-record %d, error getting ver: %x\n", rv);
3460
3461 display_pad_out(" multi-record %d, type 0x%x, format version 0x%x:",
3462 i, type, ver);
3463
3464 rv = ipmi_fru_get_multi_record_data_len(fru, i, &len);
3465 if (rv) {
3466 display_pad_out("\n multi-record %d, error getting length: %x\n",
3467 rv);
3468 continue;
3469 }
3470 data = ipmi_mem_alloc(len);
3471 if (!data) {
3472 display_pad_out("\n multi-record %d, error allocating data\n");
3473 continue;
3474 }
3475 rv = ipmi_fru_get_multi_record_data(fru, i, data, &len);
3476 if (rv) {
3477 display_pad_out("\n multi-record %d, error getting data: %x\n",
3478 rv);
3479 } else {
3480 for (j=0; j<len; j++) {
3481 if ((j > 0) && ((j % 16) == 0))
3482 display_pad_out("\n ");
3483 display_pad_out(" %2.2x", data[j]);
3484 }
3485 display_pad_out("\n");
3486 rv = ipmi_fru_multi_record_get_root_node(fru, i, &name, &node);
3487 if ( !rv ) {
3488 display_pad_out("Multi-record decode: %s", name);
3489 traverse_fru_multi_record_tree(node, 2);
3490 } else if ((rv != ENOSYS) && (rv != EINVAL)) {
3491 display_pad_out(" multi-record %d, error get root obj: %x\n ",
3492 i, rv);
3493 }
3494 }
3495 ipmi_mem_free(data);
3496 }
3497 }
3498
3499 static void
found_entity_for_fru(ipmi_entity_t * entity,char ** toks,char ** toks2,void * cb_data)3500 found_entity_for_fru(ipmi_entity_t *entity,
3501 char **toks,
3502 char **toks2,
3503 void *cb_data)
3504 {
3505 char loc[MAX_ENTITY_LOC_SIZE];
3506 ipmi_fru_t *fru = ipmi_entity_get_fru(entity);
3507
3508 display_pad_clear();
3509
3510 if (!fru) {
3511 cmd_win_out("No FRU for entity %s\n",
3512 get_entity_loc(entity, loc, sizeof(loc)));
3513 return;
3514 }
3515
3516 display_pad_out("FRU for entity %s\n",
3517 get_entity_loc(entity, loc, sizeof(loc)));
3518
3519 dump_fru_info(fru);
3520
3521 display_pad_refresh();
3522 }
3523
3524 static int
fru_cmd(char * cmd,char ** toks,void * cb_data)3525 fru_cmd(char *cmd, char **toks, void *cb_data)
3526 {
3527 entity_finder(cmd, toks, found_entity_for_fru, NULL);
3528 curr_display_type = DISPLAY_ENTITY;
3529 return 0;
3530 }
3531
3532 static void
fru_fetched(ipmi_fru_t * fru,int err,void * cb_data)3533 fru_fetched(ipmi_fru_t *fru, int err, void *cb_data)
3534 {
3535 display_pad_clear();
3536 if (err)
3537 display_pad_out("Error fetching fru: %x\n", err);
3538 else
3539 dump_fru_info(fru);
3540 display_pad_refresh();
3541 if (err != ECANCELED)
3542 ipmi_fru_destroy(fru, NULL, NULL);
3543 }
3544
3545 typedef struct fru_rec_s
3546 {
3547 unsigned char is_logical;
3548 unsigned char device_address;
3549 unsigned char device_id;
3550 unsigned char lun;
3551 unsigned char private_bus;
3552 unsigned char channel;
3553 } fru_rec_t;
3554
3555 static void
dump_fru_cmder(ipmi_domain_t * domain,void * cb_data)3556 dump_fru_cmder(ipmi_domain_t *domain, void *cb_data)
3557 {
3558 fru_rec_t *info = cb_data;
3559 int rv;
3560
3561 rv = ipmi_fru_alloc(domain,
3562 info->is_logical,
3563 info->device_address,
3564 info->device_id,
3565 info->lun,
3566 info->private_bus,
3567 info->channel,
3568 fru_fetched,
3569 NULL,
3570 NULL);
3571 if (rv)
3572 cmd_win_out("Unable to allocate fru: %x\n", rv);
3573 }
3574
3575 static int
dump_fru_cmd(char * cmd,char ** toks,void * cb_data)3576 dump_fru_cmd(char *cmd, char **toks, void *cb_data)
3577 {
3578 int rv;
3579 fru_rec_t info;
3580
3581 if (get_uchar(toks, &info.is_logical, "is_logical"))
3582 return 0;
3583 if (get_uchar(toks, &info.device_address, "device_address"))
3584 return 0;
3585 if (get_uchar(toks, &info.device_id, "device_id"))
3586 return 0;
3587 if (get_uchar(toks, &info.lun, "lun"))
3588 return 0;
3589 if (get_uchar(toks, &info.private_bus, "private_bus"))
3590 return 0;
3591 if (get_uchar(toks, &info.channel, "channel"))
3592 return 0;
3593
3594 rv = ipmi_domain_pointer_cb(domain_id, dump_fru_cmder, &info);
3595 if (rv)
3596 cmd_win_out("Unable to convert domain id to a pointer\n");
3597 else
3598 curr_display_type = DISPLAY_ENTITY;
3599
3600 return 0;
3601 }
3602
y_or_n(int val)3603 static char y_or_n(int val)
3604 {
3605 if (val)
3606 return 'y';
3607 else
3608 return 'n';
3609 }
3610
3611 #define MCCMD_DATA_SIZE 30
3612 typedef struct mccmd_info_s
3613 {
3614 ipmi_mcid_t mc_id;
3615 unsigned char lun;
3616 ipmi_msg_t msg;
3617 int found;
3618 unsigned char val;
3619 } mccmd_info_t;
3620
mc_handler(ipmi_mc_t * mc,void * cb_data)3621 void mc_handler(ipmi_mc_t *mc, void *cb_data)
3622 {
3623 unsigned char vals[4];
3624 mccmd_info_t *info = cb_data;
3625
3626 curr_display_type = DISPLAY_MC;
3627 info->found = 1;
3628 display_pad_clear();
3629 display_pad_out("MC (%x %x) - %s\n",
3630 ipmi_mc_get_channel(mc),
3631 ipmi_mc_get_address(mc),
3632 ipmi_mc_is_active(mc) ? "active" : "inactive");
3633 display_pad_out(" provides_device_sdrs: %c\n",
3634 y_or_n(ipmi_mc_provides_device_sdrs(mc)));
3635 display_pad_out(" device_available: %c\n",
3636 y_or_n(ipmi_mc_device_available(mc)));
3637 display_pad_out(" chassis_support: %c\n",
3638 y_or_n(ipmi_mc_chassis_support(mc)));
3639 display_pad_out(" bridge_support: %c\n",
3640 y_or_n(ipmi_mc_bridge_support(mc)));
3641 display_pad_out(" ipmb_event_generator: %c\n",
3642 y_or_n(ipmi_mc_ipmb_event_generator_support(mc)));
3643 display_pad_out(" ipmb_event_receiver: %c\n",
3644 y_or_n(ipmi_mc_ipmb_event_receiver_support(mc)));
3645 display_pad_out(" fru_inventory_support: %c\n",
3646 y_or_n(ipmi_mc_fru_inventory_support(mc)));
3647 display_pad_out(" sel_device_support: %c\n",
3648 y_or_n(ipmi_mc_sel_device_support(mc)));
3649 display_pad_out(" sdr_repository_support: %c\n",
3650 y_or_n(ipmi_mc_sdr_repository_support(mc)));
3651 display_pad_out(" sensor_device_support: %c\n",
3652 y_or_n(ipmi_mc_sensor_device_support(mc)));
3653 display_pad_out(" device_id: %2.2x\n",
3654 ipmi_mc_device_id(mc));
3655 display_pad_out(" device_revision: %1.1x\n",
3656 ipmi_mc_device_revision(mc));
3657 display_pad_out(" fw_revision: %d.%d%d\n",
3658 ipmi_mc_major_fw_revision(mc),
3659 ipmi_mc_minor_fw_revision(mc)>>4,
3660 ipmi_mc_minor_fw_revision(mc)&0xf);
3661 display_pad_out(" version: %d.%d\n",
3662 ipmi_mc_major_version(mc),
3663 ipmi_mc_minor_version(mc));
3664 display_pad_out(" manufacturer_id: %6.6x\n",
3665 ipmi_mc_manufacturer_id(mc));
3666 display_pad_out(" product_id: %4.4x\n",
3667 ipmi_mc_product_id(mc));
3668 ipmi_mc_aux_fw_revision(mc, vals);
3669 display_pad_out(" aux_fw_revision: %2.2x %2.2x %2.2x %2.2x\n",
3670 vals[0], vals[1], vals[2], vals[3]);
3671
3672 display_pad_out(" SEL count: %d entries, %d slots used\n",
3673 ipmi_mc_sel_count(mc), ipmi_mc_sel_entries_used(mc));
3674 }
3675
3676 int
get_mc_id(char ** toks,ipmi_mcid_t * mc_id)3677 get_mc_id(char **toks, ipmi_mcid_t *mc_id)
3678 {
3679 unsigned char val;
3680
3681 if (get_uchar(toks, &val, "mc channel"))
3682 return 1;
3683 mc_id->channel = val;
3684
3685 if (get_uchar(toks, &val, "MC num"))
3686 return 1;
3687 mc_id->mc_num = val;
3688
3689 mc_id->domain_id = domain_id;
3690 return 0;
3691 }
3692
3693 int
mc_cmd(char * cmd,char ** toks,void * cb_data)3694 mc_cmd(char *cmd, char **toks, void *cb_data)
3695 {
3696 mccmd_info_t info;
3697 int rv;
3698
3699 if (get_mc_id(toks, &info.mc_id))
3700 return 0;
3701
3702 info.found = 0;
3703 rv = ipmi_mc_pointer_noseq_cb(info.mc_id, mc_handler, &info);
3704 if (rv) {
3705 cmd_win_out("Unable to find MC\n");
3706 return 0;
3707 }
3708 if (!info.found) {
3709 cmd_win_out("Unable to find MC (%d %x)\n",
3710 info.mc_id.channel, info.mc_id.mc_num);
3711 }
3712 display_pad_refresh();
3713
3714 return 0;
3715 }
3716
mcs_handler(ipmi_domain_t * domain,ipmi_mc_t * mc,void * cb_data)3717 void mcs_handler(ipmi_domain_t *domain,
3718 ipmi_mc_t *mc,
3719 void *cb_data)
3720 {
3721 int addr;
3722 int channel;
3723
3724 addr = ipmi_mc_get_address(mc);
3725 channel = ipmi_mc_get_channel(mc);
3726 display_pad_out(" (%x %x) - %s\n", channel, addr,
3727 ipmi_mc_is_active(mc) ? "active" : "inactive");
3728 }
3729
3730 static void
mcs_cmder(ipmi_domain_t * domain,void * cb_data)3731 mcs_cmder(ipmi_domain_t *domain, void *cb_data)
3732 {
3733 ipmi_domain_iterate_mcs(domain, mcs_handler, NULL);
3734 }
3735
3736 int
mcs_cmd(char * cmd,char ** toks,void * cb_data)3737 mcs_cmd(char *cmd, char **toks, void *cb_data)
3738 {
3739 int rv;
3740
3741 display_pad_clear();
3742 curr_display_type = DISPLAY_MCS;
3743 display_pad_out("MCs:\n");
3744 rv = ipmi_domain_pointer_cb(domain_id, mcs_cmder, NULL);
3745 if (rv) {
3746 cmd_win_out("Unable to convert domain id to a pointer\n");
3747 return 0;
3748 }
3749 display_pad_refresh();
3750 return 0;
3751 }
3752
3753 static void
mccmd_rsp_handler(ipmi_mc_t * src,ipmi_msg_t * msg,void * rsp_data)3754 mccmd_rsp_handler(ipmi_mc_t *src,
3755 ipmi_msg_t *msg,
3756 void *rsp_data)
3757 {
3758 unsigned int i;
3759 unsigned char *data;
3760
3761 display_pad_clear();
3762 curr_display_type = DISPLAY_RSP;
3763 display_pad_out("Response:\n");
3764 display_pad_out(" NetFN = 0x%2.2x\n", msg->netfn);
3765 display_pad_out(" Command = 0x%2.2x\n", msg->cmd);
3766 display_pad_out(" Completion code = 0x%2.2x\n", msg->data[0]);
3767 display_pad_out(" data =");
3768 data = msg->data + 1;
3769 for (i=0; i+1<msg->data_len; i++) {
3770 if ((i != 0) && ((i % 8) == 0))
3771 display_pad_out("\n ");
3772 display_pad_out(" %2.2x", data[i]);
3773 }
3774 display_pad_out("\n");
3775 display_pad_refresh();
3776 }
3777
mccmd_handler(ipmi_mc_t * mc,void * cb_data)3778 void mccmd_handler(ipmi_mc_t *mc,
3779 void *cb_data)
3780 {
3781 mccmd_info_t *info = cb_data;
3782 int rv;
3783
3784 info->found = 1;
3785 rv = ipmi_mc_send_command(mc, info->lun, &(info->msg), mccmd_rsp_handler,
3786 NULL);
3787 if (rv)
3788 cmd_win_out("Send command failure: %x\n", rv);
3789 }
3790
3791 int
mccmd_cmd(char * cmd,char ** toks,void * cb_data)3792 mccmd_cmd(char *cmd, char **toks, void *cb_data)
3793 {
3794 mccmd_info_t info;
3795 unsigned char data[MCCMD_DATA_SIZE];
3796 unsigned int data_len;
3797 int rv;
3798
3799
3800 if (get_mc_id(toks, &info.mc_id))
3801 return 0;
3802
3803 if (get_uchar(toks, &info.lun, "LUN"))
3804 return 0;
3805
3806 if (get_uchar(toks, &info.msg.netfn, "NetFN"))
3807 return 0;
3808
3809 if (get_uchar(toks, &info.msg.cmd, "command"))
3810 return 0;
3811
3812 for (data_len=0; ; data_len++) {
3813 if (get_uchar(toks, data+data_len, NULL))
3814 break;
3815 }
3816
3817 info.msg.data_len = data_len;
3818 info.msg.data = data;
3819
3820 info.found = 0;
3821 rv = ipmi_mc_pointer_noseq_cb(info.mc_id, mccmd_handler, &info);
3822 if (rv) {
3823 cmd_win_out("Unable to convert MC id to a pointer\n");
3824 return 0;
3825 }
3826 if (!info.found) {
3827 cmd_win_out("Unable to find MC (%d %x)\n",
3828 info.mc_id.channel, info.mc_id.mc_num);
3829 }
3830 display_pad_refresh();
3831
3832 return 0;
3833 }
3834
3835 void
mc_events_enable_cb(ipmi_mc_t * mc,int err,void * cb_data)3836 mc_events_enable_cb(ipmi_mc_t *mc, int err, void *cb_data)
3837 {
3838 if (err)
3839 ui_log("Error setting events enable: 0x%x\n", err);
3840 else
3841 ui_log("Events enable set\n");
3842 }
3843
3844 void
mc_events_enable_handler(ipmi_mc_t * mc,void * cb_data)3845 mc_events_enable_handler(ipmi_mc_t *mc,
3846 void *cb_data)
3847 {
3848 mccmd_info_t *info = cb_data;
3849 int rv;
3850
3851 info->found = 1;
3852 rv = ipmi_mc_set_events_enable(mc, info->val, mc_events_enable_cb, NULL);
3853 if (rv)
3854 cmd_win_out("Set events enable failure: %x\n", rv);
3855 }
3856
3857 int
mc_events_enable_cmd(char * cmd,char ** toks,void * cb_data)3858 mc_events_enable_cmd(char *cmd, char **toks, void *cb_data)
3859 {
3860 mccmd_info_t info;
3861 int rv;
3862
3863
3864 if (get_mc_id(toks, &info.mc_id))
3865 return 0;
3866
3867 if (get_uchar(toks, &info.val, "enabled"))
3868 return 0;
3869
3870 info.found = 0;
3871 rv = ipmi_mc_pointer_noseq_cb(info.mc_id, mc_events_enable_handler, &info);
3872 if (rv) {
3873 cmd_win_out("Unable to convert MC id to a pointer\n");
3874 return 0;
3875 }
3876 if (!info.found) {
3877 cmd_win_out("Unable to find MC (%d %x)\n",
3878 info.mc_id.channel, info.mc_id.mc_num);
3879 }
3880 display_pad_refresh();
3881
3882 return 0;
3883 }
3884
3885 void
mc_events_enabled_handler(ipmi_mc_t * mc,void * cb_data)3886 mc_events_enabled_handler(ipmi_mc_t *mc,
3887 void *cb_data)
3888 {
3889 mccmd_info_t *info = cb_data;
3890
3891 info->found = 1;
3892 if (ipmi_mc_get_events_enable(mc))
3893 cmd_win_out("Events enabled\n");
3894 else
3895 cmd_win_out("Events not enabled\n");
3896 }
3897
3898 int
mc_events_enabled_cmd(char * cmd,char ** toks,void * cb_data)3899 mc_events_enabled_cmd(char *cmd, char **toks, void *cb_data)
3900 {
3901 mccmd_info_t info;
3902 int rv;
3903
3904
3905 if (get_mc_id(toks, &info.mc_id))
3906 return 0;
3907
3908 info.found = 0;
3909 rv = ipmi_mc_pointer_noseq_cb(info.mc_id, mc_events_enabled_handler, &info);
3910 if (rv) {
3911 cmd_win_out("Unable to convert MC id to a pointer\n");
3912 return 0;
3913 }
3914 if (!info.found) {
3915 cmd_win_out("Unable to find MC (%d %x)\n",
3916 info.mc_id.channel, info.mc_id.mc_num);
3917 }
3918 display_pad_refresh();
3919
3920 return 0;
3921 }
3922
3923 void
display_pef(void)3924 display_pef(void)
3925 {
3926 if (!pef) {
3927 display_pad_out("No PEF read, use readpef to fetch one\n");
3928 return;
3929 }
3930
3931 display_pad_out("PEF\n");
3932 display_pad_out(" Version: %d.%d", ipmi_pef_major_version(pef),
3933 ipmi_pef_minor_version(pef));
3934 display_pad_out(" Supports:");
3935 if (ipmi_pef_supports_diagnostic_interrupt(pef))
3936 display_pad_out(" diagnostic_interrupt");
3937 if (ipmi_pef_supports_oem_action(pef))
3938 display_pad_out(" oem_action");
3939 if (ipmi_pef_supports_power_cycle(pef))
3940 display_pad_out(" power_cycle");
3941 if (ipmi_pef_supports_reset(pef))
3942 display_pad_out(" reset");
3943 if (ipmi_pef_supports_power_down(pef))
3944 display_pad_out(" power_down");
3945 if (ipmi_pef_supports_alert(pef))
3946 display_pad_out(" alert");
3947 display_pad_out("\n");
3948 display_pad_out(" Num event filter table entries: %d\n",
3949 num_event_filter_table_entries(pef));
3950 }
3951
3952 typedef struct pef_table_s
3953 {
3954 char *name;
3955 int (*get)(ipmi_pef_config_t *pefc,
3956 unsigned int sel,
3957 unsigned int *val);
3958 char *fmt;
3959 } pef_table_t;
3960
3961 #define X(n, f) { #n, ipmi_pefconfig_get_##n, f }
3962 static pef_table_t eft_table[] =
3963 {
3964 X(enable_filter, "%d"),
3965 X(filter_type, "%d"),
3966 X(diagnostic_interrupt, "%d"),
3967 X(oem_action, "%d"),
3968 X(power_cycle, "%d"),
3969 X(reset, "%d"),
3970 X(power_down, "%d"),
3971 X(alert, "%d"),
3972 X(alert_policy_number, "%d"),
3973 X(event_severity, "0x%x"),
3974 X(generator_id_addr, "0x%x"),
3975 X(generator_id_channel_lun, "0x%x"),
3976 X(sensor_type, "0x%x"),
3977 X(sensor_number, "0x%x"),
3978 X(event_trigger, "%d"),
3979 X(data1_offset_mask, "0x%x"),
3980 X(data1_mask, "%d"),
3981 X(data1_compare1, "%d"),
3982 X(data1_compare2, "%d"),
3983 X(data2_mask, "%d"),
3984 X(data2_compare1, "%d"),
3985 X(data2_compare2, "%d"),
3986 X(data3_mask, "%d"),
3987 X(data3_compare1, "%d"),
3988 X(data3_compare2, "%d"),
3989 { NULL }
3990 };
3991 static pef_table_t apt_table[] =
3992 {
3993 X(policy_num, "%d"),
3994 X(enabled, "%d"),
3995 X(policy, "%d"),
3996 X(channel, "0x%x"),
3997 X(destination_selector, "%d"),
3998 X(alert_string_event_specific, "%d"),
3999 X(alert_string_selector, "%d"),
4000 { NULL }
4001 };
4002 static pef_table_t ask_table[] =
4003 {
4004 X(event_filter, "%d"),
4005 X(alert_string_set, "%d"),
4006 { NULL }
4007 };
4008
4009 void
display_pef_config(void)4010 display_pef_config(void)
4011 {
4012 unsigned int i, j;
4013 unsigned int val;
4014 unsigned int len;
4015 unsigned char data[128];
4016 int rv;
4017 unsigned int count;
4018
4019 if (!pef_config) {
4020 display_pad_out("No PEF config read, use readpef to fetch one\n");
4021 return;
4022 }
4023
4024 display_pad_out(" alert_startup_delay_enabled: %d\n",
4025 ipmi_pefconfig_get_alert_startup_delay_enabled(pef_config));
4026 display_pad_out(" startup_delay_enabled: %d\n",
4027 ipmi_pefconfig_get_startup_delay_enabled(pef_config));
4028 display_pad_out(" event_messages_enabled: %d\n",
4029 ipmi_pefconfig_get_event_messages_enabled(pef_config));
4030 display_pad_out(" pef_enabled: %d\n",
4031 ipmi_pefconfig_get_pef_enabled(pef_config));
4032 display_pad_out(" diagnostic_interrupt_enabled: %d\n",
4033 ipmi_pefconfig_get_diagnostic_interrupt_enabled(pef_config));
4034 display_pad_out(" oem_action_enabled: %d\n",
4035 ipmi_pefconfig_get_oem_action_enabled(pef_config));
4036 display_pad_out(" power_cycle_enabled: %d\n",
4037 ipmi_pefconfig_get_power_cycle_enabled(pef_config));
4038 display_pad_out(" reset_enabled: %d\n",
4039 ipmi_pefconfig_get_reset_enabled(pef_config));
4040 display_pad_out(" power_down_enabled: %d\n",
4041 ipmi_pefconfig_get_power_down_enabled(pef_config));
4042 display_pad_out(" alert_enabled: %d\n",
4043 ipmi_pefconfig_get_alert_enabled(pef_config));
4044
4045 if (ipmi_pefconfig_get_startup_delay(pef_config, &val) == 0)
4046 display_pad_out(" startup_delay: %d\n", val);
4047 if (ipmi_pefconfig_get_alert_startup_delay(pef_config, &val) == 0)
4048 display_pad_out(" alert_startup_delay: %d\n", val);
4049
4050 len = sizeof(data);
4051 rv = ipmi_pefconfig_get_guid(pef_config, &val, data, &len);
4052 if (!rv) {
4053 display_pad_out(" guid_enabled: %d\n", val);
4054 display_pad_out(" guid:", val);
4055 for (i=0; i<len; i++)
4056 display_pad_out(" %2.2x", data[i]);
4057 display_pad_out("\n");
4058 }
4059
4060 count = ipmi_pefconfig_get_num_event_filters(pef_config);
4061 display_pad_out(" num_event_filters: %d\n", count);
4062 for (i=0; i<count; i++) {
4063 display_pad_out(" event filter %d:\n", i+1);
4064 for (j=0; eft_table[j].name != NULL; j++) {
4065 rv = eft_table[j].get(pef_config, i, &val);
4066 display_pad_out(" %s: ", eft_table[j].name);
4067 if (rv)
4068 display_pad_out("error %x", rv);
4069 else
4070 display_pad_out(eft_table[j].fmt, val);
4071 display_pad_out("\n");
4072 }
4073 }
4074
4075 count = ipmi_pefconfig_get_num_alert_policies(pef_config);
4076 display_pad_out(" num_alert_policies: %d\n", count);
4077 for (i=0; i<count; i++) {
4078 display_pad_out(" alert policy %d:\n", i+1);
4079 for (j=0; apt_table[j].name != NULL; j++) {
4080 rv = apt_table[j].get(pef_config, i, &val);
4081 display_pad_out(" %s: ", apt_table[j].name);
4082 if (rv)
4083 display_pad_out("error %x", rv);
4084 else
4085 display_pad_out(apt_table[j].fmt, val);
4086 display_pad_out("\n");
4087 }
4088 }
4089
4090 count = ipmi_pefconfig_get_num_alert_strings(pef_config);
4091 display_pad_out(" num_alert_strings: %d\n", count);
4092 for (i=0; i<count; i++) {
4093 display_pad_out(" alert string %d:\n", i);
4094 for (j=0; ask_table[j].name != NULL; j++) {
4095 rv = ask_table[j].get(pef_config, i, &val);
4096 display_pad_out(" %s: ", ask_table[j].name);
4097 if (rv)
4098 display_pad_out("error %x", rv);
4099 else
4100 display_pad_out(ask_table[j].fmt, val);
4101 display_pad_out("\n");
4102 }
4103 len = sizeof(data);
4104 rv = ipmi_pefconfig_get_alert_string(pef_config, i, data, &len);
4105 if (rv)
4106 display_pad_out(" alert_string: error %x\n", rv);
4107 else
4108 display_pad_out(" alert_string: '%s'\n", data);
4109 }
4110 }
4111
4112 void
readpef_getconf_handler(ipmi_pef_t * pef,int err,ipmi_pef_config_t * config,void * cb_data)4113 readpef_getconf_handler(ipmi_pef_t *pef,
4114 int err,
4115 ipmi_pef_config_t *config,
4116 void *cb_data)
4117 {
4118 if (err) {
4119 ui_log("Error reading PEF config: %x\n", err);
4120 return;
4121 }
4122
4123 pef_config = config;
4124 display_pef_config();
4125 display_pad_refresh();
4126 }
4127
4128 void
readpef_alloc_handler(ipmi_pef_t * lpef,int err,void * cb_data)4129 readpef_alloc_handler(ipmi_pef_t *lpef,
4130 int err,
4131 void *cb_data)
4132 {
4133 if (err) {
4134 ui_log("Error allocating PEF: %x\n", err);
4135 return;
4136 }
4137
4138 if (!ipmi_pef_valid(lpef)) {
4139 display_pad_out("PEF is not valid\n");
4140 ipmi_pef_destroy(pef, NULL, NULL);
4141 pef = NULL;
4142 return;
4143 }
4144
4145 pef = lpef;
4146 display_pad_clear();
4147 display_pef();
4148
4149 ipmi_pef_get_config(pef, readpef_getconf_handler, NULL);
4150 }
4151
4152 void
readpef_mc_handler(ipmi_mc_t * mc,void * cb_data)4153 readpef_mc_handler(ipmi_mc_t *mc, void *cb_data)
4154 {
4155 int rv;
4156 mccmd_info_t *info = cb_data;
4157
4158 info->found = 1;
4159
4160 if (pef) {
4161 ipmi_pef_destroy(pef, NULL, NULL);
4162 pef = NULL;
4163 }
4164 if (pef_config) {
4165 ipmi_pef_free_config(pef_config);
4166 pef_config = NULL;
4167 }
4168
4169 rv = ipmi_pef_alloc(mc, readpef_alloc_handler, NULL, NULL);
4170 if (rv)
4171 cmd_win_out("Error allocating PEF");
4172 }
4173
4174 int
readpef_cmd(char * cmd,char ** toks,void * cb_data)4175 readpef_cmd(char *cmd, char **toks, void *cb_data)
4176 {
4177 mccmd_info_t info;
4178 int rv;
4179
4180 if (get_mc_id(toks, &info.mc_id))
4181 return 0;
4182
4183 info.found = 0;
4184 rv = ipmi_mc_pointer_noseq_cb(info.mc_id, readpef_mc_handler, &info);
4185 if (rv) {
4186 cmd_win_out("Unable to find MC\n");
4187 return 0;
4188 }
4189 if (!info.found) {
4190 cmd_win_out("Unable to find MC (%d %x)\n",
4191 info.mc_id.channel, info.mc_id.mc_num);
4192 }
4193 display_pad_refresh();
4194
4195 return 0;
4196 }
4197
4198 int
viewpef_cmd(char * cmd,char ** toks,void * cb_data)4199 viewpef_cmd(char *cmd, char **toks, void *cb_data)
4200 {
4201 display_pad_clear();
4202 display_pef();
4203 display_pef_config();
4204 display_pad_refresh();
4205
4206 return 0;
4207 }
4208
writepef_done(ipmi_pef_t * pef,int err,void * cb_data)4209 void writepef_done(ipmi_pef_t *pef,
4210 int err,
4211 void *cb_data)
4212 {
4213 if (err)
4214 ui_log("Error writing PEF: %x\n", err);
4215 else
4216 ui_log("PEF written\n");
4217 }
4218
4219 int
writepef_cmd(char * cmd,char ** toks,void * cb_data)4220 writepef_cmd(char *cmd, char **toks, void *cb_data)
4221 {
4222 int rv;
4223
4224 if (!pef) {
4225 cmd_win_out("No PEF to write\n");
4226 return 0;
4227 }
4228 if (!pef_config) {
4229 cmd_win_out("No PEF config to write\n");
4230 return 0;
4231 }
4232
4233 rv = ipmi_pef_set_config(pef, pef_config, writepef_done, NULL);
4234 if (rv) {
4235 cmd_win_out("Error writing pef parms: %x\n", rv);
4236 }
4237 return 0;
4238 }
4239
clearpeflock_done(ipmi_pef_t * pef,int err,void * cb_data)4240 void clearpeflock_done(ipmi_pef_t *pef,
4241 int err,
4242 void *cb_data)
4243 {
4244 if (err)
4245 ui_log("Error clearing PEF lock: %x\n", err);
4246 else
4247 ui_log("PEF lock cleared\n");
4248 }
4249
4250 static void
clearpeflock_rsp_handler(ipmi_mc_t * src,ipmi_msg_t * msg,void * rsp_data)4251 clearpeflock_rsp_handler(ipmi_mc_t *src,
4252 ipmi_msg_t *msg,
4253 void *rsp_data)
4254 {
4255 if (msg->data[0])
4256 ui_log("Error clearing PEF lock: %x\n",
4257 IPMI_IPMI_ERR_VAL(msg->data[0]));
4258 else
4259 ui_log("PEF lock cleared\n");
4260 }
4261
4262 void
clearpeflock_mc_handler(ipmi_mc_t * mc,void * cb_data)4263 clearpeflock_mc_handler(ipmi_mc_t *mc, void *cb_data)
4264 {
4265 mccmd_info_t *info = cb_data;
4266 unsigned char data[2];
4267 ipmi_msg_t msg;
4268 int rv;
4269
4270 info->found = 1;
4271
4272 data[0] = 0;
4273 data[1] = 0;
4274 msg.netfn = IPMI_SENSOR_EVENT_NETFN;
4275 msg.cmd = IPMI_SET_PEF_CONFIG_PARMS_CMD;
4276 msg.data = data;
4277 msg.data_len = 2;
4278 rv = ipmi_mc_send_command(mc, 0, &msg, clearpeflock_rsp_handler,
4279 NULL);
4280 if (rv)
4281 cmd_win_out("Send PEF clear lock failure: %x\n", rv);
4282 }
4283
4284 int
clearpeflock_cmd(char * cmd,char ** toks,void * cb_data)4285 clearpeflock_cmd(char *cmd, char **toks, void *cb_data)
4286 {
4287 mccmd_info_t info;
4288 int rv;
4289 char *mc_toks;
4290 char buf[100];
4291 char *ntoks;
4292
4293 mc_toks = strtok_r(NULL, "", toks);
4294 if (mc_toks) {
4295 strncpy(buf+2, mc_toks, sizeof(buf)-2);
4296 buf[0] = 'a';
4297 buf[1] = ' ';
4298 strtok_r(buf, " ", &ntoks);
4299 if (get_mc_id(&ntoks, &info.mc_id))
4300 return 0;
4301
4302 info.found = 0;
4303 rv = ipmi_mc_pointer_noseq_cb(info.mc_id, clearpeflock_mc_handler,
4304 &info);
4305 if (rv) {
4306 cmd_win_out("Unable to find MC\n");
4307 return 0;
4308 }
4309 if (!info.found) {
4310 cmd_win_out("Unable to find MC (%d %x)\n",
4311 info.mc_id.channel, info.mc_id.mc_num);
4312 }
4313 display_pad_refresh();
4314 } else {
4315 if (!pef) {
4316 ui_log("No PEF to write\n");
4317 return 0;
4318 }
4319
4320 ipmi_pef_clear_lock(pef, pef_config, clearpeflock_done, NULL);
4321 }
4322
4323 return 0;
4324 }
4325
4326 typedef struct setpef_parm_s
4327 {
4328 char *name;
4329 int (*set_val)(ipmi_pef_config_t *, unsigned int);
4330 int (*set_data)(ipmi_pef_config_t *, unsigned char *, unsigned int);
4331 int (*set_val_sel)(ipmi_pef_config_t *, unsigned int, unsigned int);
4332 int (*set_data_sel)(ipmi_pef_config_t *, unsigned int,
4333 unsigned char *, unsigned int);
4334 } setpef_parm_t;
4335
4336 #define N NULL
4337 #define D(x) #x
4338 #define C(x) D(x)
4339 #define H(x) ipmi_pefconfig_set_ ## x
4340 #define G(x) H(x)
4341 static setpef_parm_t pef_conf[] =
4342 {
4343 #undef V
4344 #define V startup_delay_enabled
4345 { C(V), G(V), N, N, N },
4346 #undef V
4347 #define V alert_startup_delay_enabled
4348 { C(V), G(V), N, N, N },
4349 #undef V
4350 #define V event_messages_enabled
4351 { C(V), G(V), N, N, N },
4352 #undef V
4353 #define V pef_enabled
4354 { C(V), G(V), N, N, N },
4355 #undef V
4356 #define V diagnostic_interrupt_enabled
4357 { C(V), G(V), N, N, N },
4358 #undef V
4359 #define V oem_action_enabled
4360 { C(V), G(V), N, N, N },
4361 #undef V
4362 #define V power_cycle_enabled
4363 { C(V), G(V), N, N, N },
4364 #undef V
4365 #define V reset_enabled
4366 { C(V), G(V), N, N, N },
4367 #undef V
4368 #define V power_down_enabled
4369 { C(V), G(V), N, N, N },
4370 #undef V
4371 #define V alert_enabled
4372 { C(V), G(V), N, N, N },
4373 #undef V
4374 #define V startup_delay
4375 { C(V), G(V), N, N, N },
4376 #undef V
4377 #define V alert_startup_delay
4378 { C(V), G(V), N, N, N },
4379 #undef V
4380 #define V enable_filter
4381 { C(V), N, N, G(V), N },
4382 #undef V
4383 #define V filter_type
4384 { C(V), N, N, G(V), N },
4385 #undef V
4386 #define V diagnostic_interrupt
4387 { C(V), N, N, G(V), N },
4388 #undef V
4389 #define V oem_action
4390 { C(V), N, N, G(V), N },
4391 #undef V
4392 #define V power_cycle
4393 { C(V), N, N, G(V), N },
4394 #undef V
4395 #define V reset
4396 { C(V), N, N, G(V), N },
4397 #undef V
4398 #define V power_down
4399 { C(V), N, N, G(V), N },
4400 #undef V
4401 #define V alert
4402 { C(V), N, N, G(V), N },
4403 #undef V
4404 #define V alert_policy_number
4405 { C(V), N, N, G(V), N },
4406 #undef V
4407 #define V event_severity
4408 { C(V), N, N, G(V), N },
4409 #undef V
4410 #define V generator_id_addr
4411 { C(V), N, N, G(V), N },
4412 #undef V
4413 #define V generator_id_channel_lun
4414 { C(V), N, N, G(V), N },
4415 #undef V
4416 #define V sensor_type
4417 { C(V), N, N, G(V), N },
4418 #undef V
4419 #define V sensor_number
4420 { C(V), N, N, G(V), N },
4421 #undef V
4422 #define V event_trigger
4423 { C(V), N, N, G(V), N },
4424 #undef V
4425 #define V data1_offset_mask
4426 { C(V), N, N, G(V), N },
4427 #undef V
4428 #define V data1_mask
4429 { C(V), N, N, G(V), N },
4430 #undef V
4431 #define V data1_compare1
4432 { C(V), N, N, G(V), N },
4433 #undef V
4434 #define V data1_compare2
4435 { C(V), N, N, G(V), N },
4436 #undef V
4437 #define V data2_mask
4438 { C(V), N, N, G(V), N },
4439 #undef V
4440 #define V data2_compare1
4441 { C(V), N, N, G(V), N },
4442 #undef V
4443 #define V data2_compare2
4444 { C(V), N, N, G(V), N },
4445 #undef V
4446 #define V data3_mask
4447 { C(V), N, N, G(V), N },
4448 #undef V
4449 #define V data3_compare1
4450 { C(V), N, N, G(V), N },
4451 #undef V
4452 #define V data3_compare2
4453 { C(V), N, N, G(V), N },
4454 #undef V
4455 #define V policy_num
4456 { C(V), N, N, G(V), N },
4457 #undef V
4458 #define V enabled
4459 { C(V), N, N, G(V), N },
4460 #undef V
4461 #define V channel
4462 { C(V), N, N, G(V), N },
4463 #undef V
4464 #define V destination_selector
4465 { C(V), N, N, G(V), N },
4466 #undef V
4467 #define V alert_string_event_specific
4468 { C(V), N, N, G(V), N },
4469 #undef V
4470 #define V alert_string_selector
4471 { C(V), N, N, G(V), N },
4472 #undef V
4473 #define V event_filter
4474 { C(V), N, N, G(V), N },
4475 #undef V
4476 #define V alert_string_set
4477 { C(V), N, N, G(V), N },
4478 { NULL }
4479 };
4480
4481
4482 static int
setpef_cmd(char * cmd,char ** toks,void * cb_data)4483 setpef_cmd(char *cmd, char **toks, void *cb_data)
4484 {
4485 unsigned int sel;
4486 unsigned int val;
4487 unsigned char data[30];
4488 char *name;
4489 char *str;
4490 unsigned int i;
4491 int rv = 0;
4492
4493 if (!pef_config) {
4494 cmd_win_out("No PEF config read, use readpef to fetch one\n");
4495 return 0;
4496 }
4497
4498 name = strtok_r(NULL, " \t\n", toks);
4499 if (!name) {
4500 cmd_win_out("No PEF config name given\n");
4501 return 0;
4502 }
4503
4504 for (i=0; pef_conf[i].name != NULL; i++) {
4505 if (strcmp(pef_conf[i].name, name) == 0)
4506 break;
4507 }
4508
4509 if (pef_conf[i].name == NULL) {
4510 if (strcmp(name, "guid") == 0) {
4511 for (i=0; i<sizeof(data); i++) {
4512 if (get_uchar(toks, data+i, NULL))
4513 break;
4514 }
4515 rv = ipmi_pefconfig_set_guid(pef_config, (i != 0), data, i);
4516 } else if (strcmp(name, "alert_string") == 0) {
4517 if (get_uint(toks, &sel, "selector"))
4518 return 0;
4519 str = strtok_r(NULL, "", toks);
4520 rv = ipmi_pefconfig_set_alert_string(pef_config, sel,
4521 (unsigned char *) str);
4522 } else {
4523 cmd_win_out("Invalid PEF config name: '%s'\n", name);
4524 return 0;
4525 }
4526 } else if (pef_conf[i].set_val) {
4527 if (get_uint(toks, &val, "value"))
4528 return 0;
4529 rv = pef_conf[i].set_val(pef_config, val);
4530 } else if (pef_conf[i].set_data) {
4531 for (i=0; i<sizeof(data); i++) {
4532 if (get_uchar(toks, data+i, NULL))
4533 break;
4534 }
4535 rv = pef_conf[i].set_data(pef_config, data, i);
4536 } else if (pef_conf[i].set_val_sel) {
4537 if (get_uint(toks, &sel, "selector"))
4538 return 0;
4539 if (get_uint(toks, &val, "value"))
4540 return 0;
4541 rv = pef_conf[i].set_val_sel(pef_config, sel, val);
4542 } else if (pef_conf[i].set_data_sel) {
4543 if (get_uint(toks, &sel, "selector"))
4544 return 0;
4545 for (i=0; i<sizeof(data); i++) {
4546 if (get_uchar(toks, data+i, NULL))
4547 break;
4548 }
4549 rv = pef_conf[i].set_data_sel(pef_config, sel, data, i);
4550 }
4551 if (rv)
4552 cmd_win_out("Error setting parm: 0x%x\n", rv);
4553 return 0;
4554 }
4555
4556 static void
lanparm_out_val(char * name,int rv,char * fmt,unsigned int val)4557 lanparm_out_val(char *name, int rv, char *fmt, unsigned int val)
4558 {
4559 if (rv == ENOTSUP)
4560 return;
4561 display_pad_out(" %s: ", name);
4562 if (rv)
4563 display_pad_out("err %x", rv);
4564 else
4565 display_pad_out(fmt, val);
4566 display_pad_out("\n");
4567 }
4568
4569 static void
lanparm_out_data(char * name,int rv,unsigned char * data,int len)4570 lanparm_out_data(char *name, int rv, unsigned char *data, int len)
4571 {
4572 int i;
4573 if (rv == ENOTSUP)
4574 return;
4575 display_pad_out(" %s: ", name);
4576 if (rv)
4577 display_pad_out("err %x\n", rv);
4578 else {
4579 for (i=0; i<len; i++)
4580 display_pad_out("%2.2x", data[i]);
4581 display_pad_out("\n");
4582 }
4583 }
4584
4585 void
display_lanparm_config(void)4586 display_lanparm_config(void)
4587 {
4588 unsigned int i;
4589 unsigned int val;
4590 unsigned int len;
4591 unsigned char data[128];
4592 int rv;
4593 unsigned int count;
4594
4595 if (!lanparm_config) {
4596 display_pad_out("No LANPARM config read, use readlanparm to fetch one\n");
4597 return;
4598 }
4599
4600 display_pad_out("LAN parameters:");
4601 display_pad_out(" auth supported:");
4602 if (ipmi_lanconfig_get_support_auth_oem(lanparm_config))
4603 display_pad_out(" oem");
4604 if (ipmi_lanconfig_get_support_auth_straight(lanparm_config))
4605 display_pad_out(" straight");
4606 if (ipmi_lanconfig_get_support_auth_md5(lanparm_config))
4607 display_pad_out(" md5");
4608 if (ipmi_lanconfig_get_support_auth_md2(lanparm_config))
4609 display_pad_out(" md2");
4610 if (ipmi_lanconfig_get_support_auth_none(lanparm_config))
4611 display_pad_out(" none");
4612 display_pad_out("\n");
4613
4614 display_pad_out(" ip_addr_source: %d\n",
4615 ipmi_lanconfig_get_ip_addr_source(lanparm_config));
4616 rv = ipmi_lanconfig_get_ipv4_ttl(lanparm_config, &val);
4617 lanparm_out_val("ipv4_ttl", rv, "%d", val);
4618 rv = ipmi_lanconfig_get_ipv4_flags(lanparm_config, &val);
4619 lanparm_out_val("ipv4_flags", rv, "%d", val);
4620 rv = ipmi_lanconfig_get_ipv4_precedence(lanparm_config, &val);
4621 lanparm_out_val("ipv4_precedence", rv, "%d", val);
4622 rv = ipmi_lanconfig_get_ipv4_tos(lanparm_config, &val);
4623 lanparm_out_val("ipv4_tos", rv, "%d", val);
4624
4625 for (i=0; i<5; i++) {
4626 display_pad_out(" auth enabled (%d):", i);
4627 rv = ipmi_lanconfig_get_enable_auth_oem(lanparm_config, i, &val);
4628 if (rv)
4629 display_pad_out(" oemerr%x", rv);
4630 else if (val)
4631 display_pad_out(" oem");
4632 rv = ipmi_lanconfig_get_enable_auth_straight(lanparm_config, i, &val);
4633 if (rv)
4634 display_pad_out(" straighterr%x", rv);
4635 else if (val)
4636 display_pad_out(" straight");
4637 rv = ipmi_lanconfig_get_enable_auth_md5(lanparm_config, i, &val);
4638 if (rv)
4639 display_pad_out(" md5err%x", rv);
4640 else if (val)
4641 display_pad_out(" md5");
4642 rv = ipmi_lanconfig_get_enable_auth_md2(lanparm_config, i, &val);
4643 if (rv)
4644 display_pad_out(" md2err%x", rv);
4645 else if (val)
4646 display_pad_out(" md2");
4647 rv = ipmi_lanconfig_get_enable_auth_none(lanparm_config, i, &val);
4648 if (rv)
4649 display_pad_out(" noneerr%x", rv);
4650 else if (val)
4651 display_pad_out(" none");
4652 display_pad_out("\n");
4653 }
4654
4655 len = 4;
4656 rv = ipmi_lanconfig_get_ip_addr(lanparm_config, data, &len);
4657 lanparm_out_data("ip_addr", rv, data, len);
4658 len = 6;
4659 rv = ipmi_lanconfig_get_mac_addr(lanparm_config, data, &len);
4660 lanparm_out_data("mac_addr", rv, data, len);
4661 len = 4;
4662 rv = ipmi_lanconfig_get_subnet_mask(lanparm_config, data, &len);
4663 lanparm_out_data("subnet_mask", rv, data, len);
4664 len = 2;
4665 rv = ipmi_lanconfig_get_primary_rmcp_port(lanparm_config, data, &len);
4666 lanparm_out_data("primary_rmcp_port", rv, data, len);
4667 len = 2;
4668 rv = ipmi_lanconfig_get_secondary_rmcp_port(lanparm_config, data, &len);
4669 lanparm_out_data("secondary_rmcp_port", rv, data, len);
4670
4671 rv = ipmi_lanconfig_get_bmc_generated_arps(lanparm_config, &val);
4672 lanparm_out_val("bmc_generated_arps", rv, "%d", val);
4673 rv = ipmi_lanconfig_get_bmc_generated_garps(lanparm_config, &val);
4674 lanparm_out_val("bmc_generated_garps", rv, "%d", val);
4675 rv = ipmi_lanconfig_get_garp_interval(lanparm_config, &val);
4676 lanparm_out_val("garp_interval", rv, "%d", val);
4677
4678 len = 4;
4679 rv = ipmi_lanconfig_get_default_gateway_ip_addr(lanparm_config, data, &len);
4680 lanparm_out_data("default_gateway_ip_addr", rv, data, len);
4681 len = 6;
4682 rv = ipmi_lanconfig_get_default_gateway_mac_addr(lanparm_config, data, &len);
4683 lanparm_out_data("default_gateway_mac_addr", rv, data, len);
4684 len = 4;
4685 rv = ipmi_lanconfig_get_backup_gateway_ip_addr(lanparm_config, data, &len);
4686 lanparm_out_data("backup_gateway_ip_addr", rv, data, len);
4687 len = 6;
4688 rv = ipmi_lanconfig_get_backup_gateway_mac_addr(lanparm_config, data, &len);
4689 lanparm_out_data("backup_gateway_mac_addr", rv, data, len);
4690
4691 len = 18;
4692 rv = ipmi_lanconfig_get_community_string(lanparm_config, data, &len);
4693 display_pad_out(" community_string: ");
4694 if (rv)
4695 display_pad_out("err: %x\n", rv);
4696 else
4697 display_pad_out("%s\n", data);
4698
4699 count = ipmi_lanconfig_get_num_alert_destinations(lanparm_config);
4700 display_pad_out(" num_alert_destinations: %d\n", count);
4701 for (i=0; i<count; i++) {
4702 display_pad_out(" destination %d:\n", i);
4703 rv = ipmi_lanconfig_get_alert_ack(lanparm_config, i, &val);
4704 lanparm_out_val(" alert_ack", rv, "%d", val);
4705 rv = ipmi_lanconfig_get_dest_type(lanparm_config, i, &val);
4706 lanparm_out_val(" dest_type", rv, "%d", val);
4707 rv = ipmi_lanconfig_get_alert_retry_interval(lanparm_config, i, &val);
4708 lanparm_out_val(" alert_retry_interval", rv, "%d", val);
4709 rv = ipmi_lanconfig_get_max_alert_retries(lanparm_config, i, &val);
4710 lanparm_out_val(" max_alert_retries", rv, "%d", val);
4711 rv = ipmi_lanconfig_get_dest_format(lanparm_config, i, &val);
4712 lanparm_out_val(" dest_format", rv, "%d", val);
4713 rv = ipmi_lanconfig_get_gw_to_use(lanparm_config, i, &val);
4714 lanparm_out_val(" gw_to_use", rv, "%d", val);
4715 len = 4;
4716 rv = ipmi_lanconfig_get_dest_ip_addr(lanparm_config, i, data, &len);
4717 lanparm_out_data(" dest_ip_addr", rv, data, len);
4718 len = 6;
4719 rv = ipmi_lanconfig_get_dest_mac_addr(lanparm_config, i, data, &len);
4720 lanparm_out_data(" dest_mac_addr", rv, data, len);
4721 }
4722 }
4723
4724 typedef struct lanparm_info_s
4725 {
4726 ipmi_mcid_t mc_id;
4727 unsigned char lun;
4728 unsigned char channel;
4729 ipmi_msg_t msg;
4730 int found;
4731 } lanparm_info_t;
4732
4733 void
readlanparm_getconf_handler(ipmi_lanparm_t * lanparm,int err,ipmi_lan_config_t * config,void * cb_data)4734 readlanparm_getconf_handler(ipmi_lanparm_t *lanparm,
4735 int err,
4736 ipmi_lan_config_t *config,
4737 void *cb_data)
4738 {
4739 if (err) {
4740 ui_log("Error reading LANPARM config: %x\n", err);
4741 return;
4742 }
4743
4744 lanparm_config = config;
4745 display_pad_clear();
4746 display_lanparm_config();
4747 display_pad_refresh();
4748 }
4749
4750 void
readlanparm_mc_handler(ipmi_mc_t * mc,void * cb_data)4751 readlanparm_mc_handler(ipmi_mc_t *mc, void *cb_data)
4752 {
4753 int rv;
4754 lanparm_info_t *info = cb_data;
4755
4756 info->found = 1;
4757
4758 if (lanparm) {
4759 ipmi_lanparm_destroy(lanparm, NULL, NULL);
4760 lanparm = NULL;
4761 }
4762 if (lanparm_config) {
4763 ipmi_lan_free_config(lanparm_config);
4764 lanparm_config = NULL;
4765 }
4766
4767 rv = ipmi_lanparm_alloc(mc, info->channel, &lanparm);
4768 if (rv) {
4769 cmd_win_out("failed lanparm allocation: %x\n", rv);
4770 return;
4771 }
4772
4773 rv = ipmi_lan_get_config(lanparm, readlanparm_getconf_handler, NULL);
4774 }
4775
4776 int
readlanparm_cmd(char * cmd,char ** toks,void * cb_data)4777 readlanparm_cmd(char *cmd, char **toks, void *cb_data)
4778 {
4779 lanparm_info_t info;
4780 int rv;
4781 unsigned char val;
4782
4783 if (get_mc_id(toks, &info.mc_id))
4784 return 0;
4785
4786 if (get_uchar(toks, &val, "lanparm channel"))
4787 return 0;
4788 info.channel = val;
4789
4790 info.found = 0;
4791 rv = ipmi_mc_pointer_noseq_cb(info.mc_id, readlanparm_mc_handler, &info);
4792 if (rv) {
4793 cmd_win_out("Unable to find MC\n");
4794 return 0;
4795 }
4796 if (!info.found) {
4797 cmd_win_out("Unable to find MC (%d %x)\n",
4798 info.mc_id.channel, info.mc_id.mc_num);
4799 }
4800 display_pad_refresh();
4801
4802 return 0;
4803 }
4804
4805 int
viewlanparm_cmd(char * cmd,char ** toks,void * cb_data)4806 viewlanparm_cmd(char *cmd, char **toks, void *cb_data)
4807 {
4808 display_pad_clear();
4809 display_lanparm_config();
4810 display_pad_refresh();
4811
4812 return 0;
4813 }
4814
writelanparm_done(ipmi_lanparm_t * lanparm,int err,void * cb_data)4815 void writelanparm_done(ipmi_lanparm_t *lanparm,
4816 int err,
4817 void *cb_data)
4818 {
4819 if (err)
4820 ui_log("Error writing LANPARM: %x\n", err);
4821 else
4822 ui_log("LANPARM written\n");
4823 }
4824
4825 int
writelanparm_cmd(char * cmd,char ** toks,void * cb_data)4826 writelanparm_cmd(char *cmd, char **toks, void *cb_data)
4827 {
4828 int rv;
4829
4830 if (!lanparm) {
4831 cmd_win_out("No LANPARM to write\n");
4832 return 0;
4833 }
4834 if (!lanparm_config) {
4835 cmd_win_out("No LANPARM config to write\n");
4836 return 0;
4837 }
4838
4839 rv = ipmi_lan_set_config(lanparm, lanparm_config, writelanparm_done, NULL);
4840 if (rv) {
4841 cmd_win_out("Error writing lan parms: %x\n", rv);
4842 }
4843 return 0;
4844 }
4845
clearlanparmlock_done(ipmi_lanparm_t * lanparm,int err,void * cb_data)4846 void clearlanparmlock_done(ipmi_lanparm_t *lanparm,
4847 int err,
4848 void *cb_data)
4849 {
4850 if (err)
4851 ui_log("Error clearing LANPARM lock: %x\n", err);
4852 else
4853 ui_log("LANPARM lock cleared\n");
4854 }
4855
4856 static void
clearlanparmlock_rsp_handler(ipmi_mc_t * src,ipmi_msg_t * msg,void * rsp_data)4857 clearlanparmlock_rsp_handler(ipmi_mc_t *src,
4858 ipmi_msg_t *msg,
4859 void *rsp_data)
4860 {
4861 if (msg->data[0])
4862 ui_log("Error clearing LANPARM lock: %x\n",
4863 IPMI_IPMI_ERR_VAL(msg->data[0]));
4864 else
4865 ui_log("LANPARM lock cleared\n");
4866 }
4867
4868 void
clearlanparmlock_mc_handler(ipmi_mc_t * mc,void * cb_data)4869 clearlanparmlock_mc_handler(ipmi_mc_t *mc, void *cb_data)
4870 {
4871 lanparm_info_t *info = cb_data;
4872 unsigned char data[3];
4873 ipmi_msg_t msg;
4874 int rv;
4875
4876 info->found = 1;
4877
4878 data[0] = info->channel;
4879 data[1] = 0;
4880 data[2] = 0;
4881 msg.netfn = IPMI_TRANSPORT_NETFN;
4882 msg.cmd = IPMI_SET_LAN_CONFIG_PARMS_CMD;
4883 msg.data = data;
4884 msg.data_len = 3;
4885 rv = ipmi_mc_send_command(mc, 0, &msg, clearlanparmlock_rsp_handler,
4886 NULL);
4887 if (rv)
4888 cmd_win_out("Send LANPARM clear lock failure: %x\n", rv);
4889 }
4890
4891 int
clearlanparmlock_cmd(char * cmd,char ** toks,void * cb_data)4892 clearlanparmlock_cmd(char *cmd, char **toks, void *cb_data)
4893 {
4894 lanparm_info_t info;
4895 int rv;
4896 char *mc_toks;
4897 char buf[100];
4898 char *ntoks;
4899 unsigned char val;
4900
4901 mc_toks = strtok_r(NULL, "", toks);
4902 if (mc_toks) {
4903 strncpy(buf+2, mc_toks, sizeof(buf)-2);
4904 buf[0] = 'a';
4905 buf[1] = ' ';
4906 strtok_r(buf, " ", &ntoks);
4907 if (get_mc_id(&ntoks, &info.mc_id))
4908 return 0;
4909
4910 if (get_uchar(&ntoks, &val, "lanparm channel"))
4911 return 0;
4912 info.channel = val;
4913
4914 info.found = 0;
4915 rv = ipmi_mc_pointer_noseq_cb(info.mc_id, clearlanparmlock_mc_handler,
4916 &info);
4917 if (rv) {
4918 cmd_win_out("Unable to find MC\n");
4919 return 0;
4920 }
4921 if (!info.found) {
4922 cmd_win_out("Unable to find MC (%d %x)\n",
4923 info.mc_id.channel, info.mc_id.mc_num);
4924 }
4925 display_pad_refresh();
4926 } else {
4927 if (!lanparm) {
4928 ui_log("No LANPARM to write\n");
4929 return 0;
4930 }
4931
4932 ipmi_lan_clear_lock(lanparm, lanparm_config,
4933 clearlanparmlock_done, NULL);
4934 }
4935
4936 return 0;
4937 }
4938
4939 typedef struct setlan_parm_s
4940 {
4941 char *name;
4942 int (*set_val)(ipmi_lan_config_t *, unsigned int);
4943 int (*set_data)(ipmi_lan_config_t *, unsigned char *, unsigned int);
4944 int (*set_val_sel)(ipmi_lan_config_t *, unsigned int, unsigned int);
4945 int (*set_data_sel)(ipmi_lan_config_t *, unsigned int,
4946 unsigned char *, unsigned int);
4947 } setlan_parm_t;
4948
4949 #undef N
4950 #define N NULL
4951 #undef D
4952 #define D(x) #x
4953 #undef C
4954 #define C(x) D(x)
4955 #undef H
4956 #define H(x) ipmi_lanconfig_set_ ## x
4957 #undef G
4958 #define G(x) H(x)
4959 static setlan_parm_t lan_conf[] =
4960 {
4961 #undef V
4962 #define V ip_addr_source
4963 { C(V), G(V), N, N, N },
4964 #undef V
4965 #define V ipv4_ttl
4966 { C(V), G(V), N, N, N },
4967 #undef V
4968 #define V ipv4_flags
4969 { C(V), G(V), N, N, N },
4970 #undef V
4971 #define V ipv4_precedence
4972 { C(V), G(V), N, N, N },
4973 #undef V
4974 #define V ipv4_tos
4975 { C(V), G(V), N, N, N },
4976 #undef V
4977 #define V enable_auth_oem
4978 { C(V), N, N, G(V), N },
4979 #undef V
4980 #define V enable_auth_straight
4981 { C(V), N, N, G(V), N },
4982 #undef V
4983 #define V enable_auth_md5
4984 { C(V), N, N, G(V), N },
4985 #undef V
4986 #define V enable_auth_md2
4987 { C(V), N, N, G(V), N },
4988 #undef V
4989 #define V enable_auth_none
4990 { C(V), N, N, G(V), N },
4991 #undef V
4992 #define V ip_addr
4993 { C(V), N, G(V), N, N },
4994 #undef V
4995 #define V mac_addr
4996 { C(V), N, G(V), N, N },
4997 #undef V
4998 #define V subnet_mask
4999 { C(V), N, G(V), N, N },
5000 #undef V
5001 #define V primary_rmcp_port
5002 { C(V), N, G(V), N, N },
5003 #undef V
5004 #define V secondary_rmcp_port
5005 { C(V), N, G(V), N, N },
5006 #undef V
5007 #define V bmc_generated_arps
5008 { C(V), G(V), N, N, N },
5009 #undef V
5010 #define V bmc_generated_garps
5011 { C(V), G(V), N, N, N },
5012 #undef V
5013 #define V garp_interval
5014 { C(V), G(V), N, N, N },
5015 #undef V
5016 #define V default_gateway_ip_addr
5017 { C(V), N, G(V), N, N },
5018 #undef V
5019 #define V default_gateway_mac_addr
5020 { C(V), N, G(V), N, N },
5021 #undef V
5022 #define V backup_gateway_ip_addr
5023 { C(V), N, G(V), N, N },
5024 #undef V
5025 #define V backup_gateway_mac_addr
5026 { C(V), N, G(V), N, N },
5027 #undef V
5028 #define V alert_ack
5029 { C(V), N, N, G(V), N },
5030 #undef V
5031 #define V dest_type
5032 { C(V), N, N, G(V), N },
5033 #undef V
5034 #define V alert_retry_interval
5035 { C(V), N, N, G(V), N },
5036 #undef V
5037 #define V max_alert_retries
5038 { C(V), N, N, G(V), N },
5039 #undef V
5040 #define V dest_format
5041 { C(V), N, N, G(V), N },
5042 #undef V
5043 #define V gw_to_use
5044 { C(V), N, N, G(V), N },
5045 #undef V
5046 #define V dest_ip_addr
5047 { C(V), N, N, N, G(V) },
5048 #undef V
5049 #define V dest_mac_addr
5050 { C(V), N, N, N, G(V) },
5051 };
5052
5053
5054 static int
setlanparm_cmd(char * cmd,char ** toks,void * cb_data)5055 setlanparm_cmd(char *cmd, char **toks, void *cb_data)
5056 {
5057 unsigned int sel;
5058 unsigned int val;
5059 unsigned char data[30];
5060 char *name;
5061 char *str;
5062 unsigned int i, j;
5063 int rv = 0;
5064
5065 if (!lanparm_config) {
5066 cmd_win_out("No LAN config read, use readlan to fetch one\n");
5067 return 0;
5068 }
5069
5070 name = strtok_r(NULL, " \t\n", toks);
5071 if (!name) {
5072 cmd_win_out("No LAN config name given\n");
5073 return 0;
5074 }
5075
5076 for (i=0; lan_conf[i].name != NULL; i++) {
5077 if (strcmp(lan_conf[i].name, name) == 0)
5078 break;
5079 }
5080
5081 if (lan_conf[i].name == NULL) {
5082 if (strcmp(name, "community_string") == 0) {
5083 if (get_uint(toks, &sel, "selector"))
5084 return 0;
5085 str = strtok_r(NULL, "", toks);
5086 rv = ipmi_lanconfig_set_community_string(lanparm_config,
5087 (unsigned char *) str,
5088 strlen(str));
5089 } else {
5090 cmd_win_out("Invalid LAN config name: '%s'\n", name);
5091 return 0;
5092 }
5093 } else if (lan_conf[i].set_val) {
5094 if (get_uint(toks, &val, "value"))
5095 return 0;
5096 rv = lan_conf[i].set_val(lanparm_config, val);
5097 } else if (lan_conf[i].set_data) {
5098 for (j=0; j<sizeof(data); j++) {
5099 if (get_uchar(toks, data+j, NULL))
5100 break;
5101 }
5102 rv = lan_conf[i].set_data(lanparm_config, data, j);
5103 } else if (lan_conf[i].set_val_sel) {
5104 if (get_uint(toks, &sel, "selector"))
5105 return 0;
5106 if (get_uint(toks, &val, "value"))
5107 return 0;
5108 rv = lan_conf[i].set_val_sel(lanparm_config, sel, val);
5109 } else if (lan_conf[i].set_data_sel) {
5110 if (get_uint(toks, &sel, "selector"))
5111 return 0;
5112 for (j=0; j<sizeof(data); j++) {
5113 if (get_uchar(toks, data+j, NULL))
5114 break;
5115 }
5116 rv = lan_conf[i].set_data_sel(lanparm_config, sel, data, j);
5117 }
5118 if (rv)
5119 cmd_win_out("Error setting parm: 0x%x\n", rv);
5120 return 0;
5121 }
5122
5123 static ipmi_pet_t *pet;
5124
5125 typedef struct pet_info_s
5126 {
5127 unsigned int connection;
5128 unsigned int channel;
5129 struct in_addr ip_addr;
5130 unsigned char mac_addr[6];
5131 unsigned int eft_sel;
5132 unsigned int policy_num;
5133 unsigned int apt_sel;
5134 unsigned int lan_dest_sel;
5135 } pet_info_t;
5136
5137 static void
pet_done(ipmi_pet_t * pet,int err,void * cb_data)5138 pet_done(ipmi_pet_t *pet, int err, void *cb_data)
5139 {
5140 if (err)
5141 ui_log("Error setting pet: %x\n", err);
5142 else
5143 ui_log("PET set");
5144 }
5145
5146 static void
pet_domain_cb(ipmi_domain_t * domain,void * cb_data)5147 pet_domain_cb(ipmi_domain_t *domain, void *cb_data)
5148 {
5149 pet_info_t *info = cb_data;
5150 int rv;
5151
5152 rv = ipmi_pet_create(domain,
5153 info->connection,
5154 info->channel,
5155 info->ip_addr,
5156 info->mac_addr,
5157 info->eft_sel,
5158 info->policy_num,
5159 info->apt_sel,
5160 info->lan_dest_sel,
5161 pet_done,
5162 NULL,
5163 &pet);
5164 if (rv)
5165 cmd_win_out("Error creating PET: %x\n", rv);
5166 }
5167
5168 static int
pet_cmd(char * cmd,char ** toks,void * cb_data)5169 pet_cmd(char *cmd, char **toks, void *cb_data)
5170 {
5171 pet_info_t info;
5172 int rv;
5173
5174 if (pet) {
5175 ipmi_pet_destroy(pet, NULL, NULL);
5176 pet = NULL;
5177 }
5178
5179 if (get_uint(toks, &info.connection, "connection"))
5180 return 0;
5181 if (get_uint(toks, &info.channel, "channel"))
5182 return 0;
5183 if (get_ip_addr(toks, &info.ip_addr, "IP address"))
5184 return 0;
5185 if (get_mac_addr(toks, info.mac_addr, "MAC address"))
5186 return 0;
5187 if (get_uint(toks, &info.eft_sel, "eft selector"))
5188 return 0;
5189 if (get_uint(toks, &info.policy_num, "policy_num"))
5190 return 0;
5191 if (get_uint(toks, &info.apt_sel, "apt selector"))
5192 return 0;
5193 if (get_uint(toks, &info.lan_dest_sel, "LAN dest selector"))
5194 return 0;
5195
5196 rv = ipmi_domain_pointer_cb(domain_id, pet_domain_cb, &info);
5197 if (rv)
5198 cmd_win_out("Error converting domain");
5199 return 0;
5200 }
5201
5202 typedef struct msg_cmd_data_s
5203 {
5204 unsigned char data[MCCMD_DATA_SIZE];
5205 unsigned int data_len;
5206 ipmi_ipmb_addr_t addr;
5207 ipmi_msg_t msg;
5208 } msg_cmd_data_t;
5209
5210 static int
mccmd_addr_rsp_handler(ipmi_domain_t * domain,ipmi_msgi_t * rspi)5211 mccmd_addr_rsp_handler(ipmi_domain_t *domain, ipmi_msgi_t *rspi)
5212 {
5213 ipmi_msg_t *msg = &rspi->msg;
5214 unsigned int i;
5215 unsigned char *data;
5216
5217 display_pad_clear();
5218 curr_display_type = DISPLAY_RSP;
5219 display_pad_out("Response:\n");
5220 display_pad_out(" NetFN = 0x%2.2x\n", msg->netfn);
5221 display_pad_out(" Command = 0x%2.2x\n", msg->cmd);
5222 display_pad_out(" Completion code = 0x%2.2x\n", msg->data[0]);
5223 display_pad_out(" data =");
5224 data = msg->data + 1;
5225 for (i=0; i+1<msg->data_len; i++) {
5226 if ((i != 0) && ((i % 8) == 0))
5227 display_pad_out("\n ");
5228 display_pad_out(" %2.2x", data[i]);
5229 }
5230 display_pad_out("\n");
5231 display_pad_refresh();
5232 return IPMI_MSG_ITEM_NOT_USED;
5233 }
5234
5235 static void
msg_cmder(ipmi_domain_t * domain,void * cb_data)5236 msg_cmder(ipmi_domain_t *domain, void *cb_data)
5237 {
5238 msg_cmd_data_t *info = cb_data;
5239 int rv;
5240
5241 rv = ipmi_send_command_addr(domain,
5242 (ipmi_addr_t *) &(info->addr),
5243 sizeof(info->addr),
5244 &info->msg,
5245 mccmd_addr_rsp_handler,
5246 NULL, NULL);
5247 if (rv)
5248 cmd_win_out("Send command failure: %x\n", rv);
5249 }
5250
5251 static int
msg_cmd(char * cmd,char ** toks,void * cb_data)5252 msg_cmd(char *cmd, char **toks, void *cb_data)
5253 {
5254 msg_cmd_data_t info;
5255 unsigned int channel;
5256 int rv;
5257
5258 info.addr.addr_type = IPMI_IPMB_ADDR_TYPE;
5259 if (get_uint(toks, &channel, "channel"))
5260 return 0;
5261 info.addr.channel = channel;
5262
5263 if (get_uchar(toks, &info.addr.slave_addr, "slave address"))
5264 return 0;
5265
5266 if (info.addr.slave_addr == 0) {
5267 info.addr.addr_type = IPMI_IPMB_BROADCAST_ADDR_TYPE;
5268 if (get_uchar(toks, &info.addr.slave_addr, "slave address"))
5269 return 0;
5270 }
5271
5272 if (get_uchar(toks, &info.addr.lun, "LUN"))
5273 return 0;
5274
5275 if (get_uchar(toks, &info.msg.netfn, "NetFN"))
5276 return 0;
5277
5278 if (get_uchar(toks, &info.msg.cmd, "command"))
5279 return 0;
5280
5281 for (info.data_len=0; ; info.data_len++) {
5282 if (get_uchar(toks, info.data+info.data_len, NULL))
5283 break;
5284 }
5285
5286 info.msg.data_len = info.data_len;
5287 info.msg.data = info.data;
5288
5289 rv = ipmi_domain_pointer_cb(domain_id, msg_cmder, &info);
5290 if (rv) {
5291 cmd_win_out("Unable to convert domain id to a pointer\n");
5292 return 0;
5293 }
5294
5295 display_pad_refresh();
5296
5297 return 0;
5298 }
5299
5300 static void
set_control(ipmi_control_t * control,void * cb_data)5301 set_control(ipmi_control_t *control, void *cb_data)
5302 {
5303 char **toks = cb_data;
5304 int num_vals;
5305 int i;
5306 int *vals = NULL;
5307 unsigned char *cvals = NULL;
5308 char *tok;
5309 char *estr;
5310 int rv;
5311 int control_type;
5312
5313 control_type = ipmi_control_get_type(control);
5314 switch (control_type) {
5315 case IPMI_CONTROL_LIGHT:
5316 if (ipmi_control_light_set_with_setting(control)) {
5317 ipmi_light_setting_t *setting;
5318
5319 num_vals = ipmi_control_get_num_vals(control);
5320 setting = ipmi_alloc_light_settings(num_vals);
5321 if (!setting) {
5322 cmd_win_out("set_control: out of memory\n");
5323 goto out;
5324 }
5325
5326 for (i=0; i<num_vals; i++) {
5327 unsigned int val;
5328
5329 if (get_uint(toks, &val, "light color"))
5330 goto out_free_light;
5331 ipmi_light_setting_set_color(setting, i, val);
5332
5333 if (get_uint(toks, &val, "light on time"))
5334 goto out_free_light;
5335 ipmi_light_setting_set_on_time(setting, i, val);
5336
5337 if (get_uint(toks, &val, "light off time"))
5338 goto out_free_light;
5339 ipmi_light_setting_set_off_time(setting, i, val);
5340
5341 if (get_uint(toks, &val, "local control"))
5342 goto out_free_light;
5343 ipmi_light_setting_set_local_control(setting, i, val);
5344 }
5345
5346 rv = ipmi_control_set_light(control, setting, NULL, NULL);
5347 if (rv) {
5348 cmd_win_out("set_control: Returned error 0x%x\n", rv);
5349 }
5350 out_free_light:
5351 ipmi_free_light_settings(setting);
5352 break;
5353 }
5354 /* FALLTHRU */
5355 case IPMI_CONTROL_RELAY:
5356 case IPMI_CONTROL_ALARM:
5357 case IPMI_CONTROL_RESET:
5358 case IPMI_CONTROL_ONE_SHOT_RESET:
5359 case IPMI_CONTROL_POWER:
5360 case IPMI_CONTROL_FAN_SPEED:
5361 case IPMI_CONTROL_OUTPUT:
5362 case IPMI_CONTROL_ONE_SHOT_OUTPUT:
5363 num_vals = ipmi_control_get_num_vals(control);
5364 vals = ipmi_mem_alloc(sizeof(*vals) * num_vals);
5365 if (!vals) {
5366 cmd_win_out("set_control: out of memory\n");
5367 goto out;
5368 }
5369
5370 for (i=0; i<num_vals; i++) {
5371 tok = strtok_r(NULL, " \t\n", toks);
5372 if (!tok) {
5373 cmd_win_out("set_control: Value %d is not present\n", i);
5374 goto out_bcon;
5375 }
5376 vals[i] = strtol(tok, &estr, 0);
5377 if (*estr != '\0') {
5378 cmd_win_out("set_control: Value %d is invalid\n", i);
5379 goto out_bcon;
5380 }
5381 }
5382
5383 rv = ipmi_control_set_val(control, vals, NULL, NULL);
5384 if (rv) {
5385 cmd_win_out("set_control: Returned error 0x%x\n", rv);
5386 }
5387 out_bcon:
5388 break;
5389
5390 case IPMI_CONTROL_DISPLAY:
5391 break;
5392
5393 case IPMI_CONTROL_IDENTIFIER:
5394 num_vals = ipmi_control_identifier_get_max_length(control);
5395 cvals = ipmi_mem_alloc(sizeof(*cvals) * num_vals);
5396 if (!cvals) {
5397 cmd_win_out("set_control: out of memory\n");
5398 goto out;
5399 }
5400
5401 for (i=0; i<num_vals; i++) {
5402 tok = strtok_r(NULL, " \t\n", toks);
5403 if (!tok) {
5404 cmd_win_out("set_control: Value %d is not present\n", i);
5405 goto out;
5406 }
5407 cvals[i] = strtol(tok, &estr, 0);
5408 if (*estr != '\0') {
5409 cmd_win_out("set_control: Value %d is invalid\n", i);
5410 goto out;
5411 }
5412 }
5413
5414 rv = ipmi_control_identifier_set_val(control, cvals, num_vals,
5415 NULL, NULL);
5416 if (rv) {
5417 cmd_win_out("set_control: Returned error 0x%x\n", rv);
5418 }
5419 break;
5420 }
5421 out:
5422 if (vals)
5423 ipmi_mem_free(vals);
5424 if (cvals)
5425 ipmi_mem_free(cvals);
5426 }
5427
5428 static int
set_control_cmd(char * cmd,char ** toks,void * cb_data)5429 set_control_cmd(char *cmd, char **toks, void *cb_data)
5430 {
5431 int rv;
5432
5433 if (curr_display_type != DISPLAY_CONTROL) {
5434 cmd_win_out("The current displayed item is not a control\n");
5435 goto out;
5436 }
5437
5438 rv = ipmi_control_pointer_cb(curr_control_id, set_control, toks);
5439 if (rv)
5440 cmd_win_out("set_control: Unable to get control pointer: 0x%x\n", rv);
5441
5442 out:
5443 return 0;
5444 }
5445
5446 static void
delevent_cb(ipmi_domain_t * domain,int err,void * cb_data)5447 delevent_cb(ipmi_domain_t *domain, int err, void *cb_data)
5448 {
5449 if (err)
5450 ui_log("Error deleting log: %x\n", err);
5451 else
5452 ui_log("log deleted\n");
5453 }
5454
5455 typedef struct delevent_info_s
5456 {
5457 ipmi_mcid_t mc_id;
5458 unsigned int record_id;
5459 int rv;
5460 } delevent_info_t;
5461
5462 static void
delevent_cmder(ipmi_domain_t * domain,void * cb_data)5463 delevent_cmder(ipmi_domain_t *domain, void *cb_data)
5464 {
5465 int rv;
5466 delevent_info_t *info = cb_data;
5467 ipmi_event_t *event, *n;
5468 int found = 0;
5469
5470 info->mc_id.domain_id = domain_id;
5471
5472 event = ipmi_domain_first_event(domain);
5473 while (event) {
5474 if ((ipmi_cmp_mc_id_noseq(ipmi_event_get_mcid(event),info->mc_id) == 0)
5475 && (ipmi_event_get_record_id(event) == info->record_id))
5476 {
5477 rv = ipmi_domain_del_event(domain, event, delevent_cb, NULL);
5478 if (rv)
5479 cmd_win_out("error deleting log: %x\n", rv);
5480 ipmi_event_free(event);
5481 found = 1;
5482 break;
5483 } else {
5484 n = ipmi_domain_next_event(domain, event);
5485 ipmi_event_free(event);
5486 event = n;
5487 }
5488 }
5489 if (!found)
5490 cmd_win_out("log not found\n");
5491 }
5492
5493 static int
delevent_cmd(char * cmd,char ** toks,void * cb_data)5494 delevent_cmd(char *cmd, char **toks, void *cb_data)
5495 {
5496 delevent_info_t info;
5497 int rv;
5498
5499 if (get_mc_id(toks, &info.mc_id))
5500 return 0;
5501
5502 if (get_uint(toks, &info.record_id, "record id"))
5503 return 0;
5504
5505 rv = ipmi_domain_pointer_cb(domain_id, delevent_cmder, &info);
5506 if (rv) {
5507 cmd_win_out("Unable to convert domain id to a pointer\n");
5508 return 0;
5509 }
5510 return 0;
5511 }
5512
5513 static void
addevent_cb(ipmi_mc_t * mc,unsigned int record_id,int err,void * cb_data)5514 addevent_cb(ipmi_mc_t *mc, unsigned int record_id, int err, void *cb_data)
5515 {
5516 if (err)
5517 ui_log("Error adding event: %x\n", err);
5518 else
5519 ui_log("event 0x%4.4x added\n", record_id);
5520 }
5521
5522 typedef struct addevent_info_s
5523 {
5524 ipmi_mcid_t mc_id;
5525 unsigned int record_id;
5526 unsigned int type;
5527 ipmi_time_t timestamp;
5528 unsigned char data[13];
5529 } addevent_info_t;
5530
5531 static void
addevent_cmder(ipmi_mc_t * mc,void * cb_data)5532 addevent_cmder(ipmi_mc_t *mc, void *cb_data)
5533 {
5534 int rv;
5535 addevent_info_t *info = cb_data;
5536 ipmi_event_t *event;
5537
5538 event = ipmi_event_alloc(ipmi_mc_convert_to_id(mc),
5539 info->record_id,
5540 info->type,
5541 info->timestamp,
5542 info->data,
5543 13);
5544 if (!event) {
5545 cmd_win_out("Could not allocate event\n");
5546 return;
5547 }
5548
5549 rv = ipmi_mc_add_event_to_sel(mc, event, addevent_cb, NULL);
5550 if (rv)
5551 cmd_win_out("Unable to send add event: %x\n", rv);
5552 ipmi_event_free(event);
5553 }
5554
5555 static int
addevent_cmd(char * cmd,char ** toks,void * cb_data)5556 addevent_cmd(char *cmd, char **toks, void *cb_data)
5557 {
5558 addevent_info_t info;
5559 int rv;
5560 int i;
5561 struct timeval time;
5562
5563 if (get_mc_id(toks, &info.mc_id))
5564 return 0;
5565
5566 if (get_uint(toks, &info.record_id, "record id"))
5567 return 0;
5568
5569 if (get_uint(toks, &info.type, "record type"))
5570 return 0;
5571
5572 for (i=0; i<13; i++) {
5573 if (get_uchar(toks, &info.data[i], "data"))
5574 return 0;
5575 }
5576
5577 ipmi_ui_os_hnd->get_monotonic_time(ipmi_ui_os_hnd, &time);
5578 info.timestamp = time.tv_sec * 1000000000;
5579
5580 rv = ipmi_mc_pointer_noseq_cb(info.mc_id, addevent_cmder, &info);
5581 if (rv) {
5582 cmd_win_out("Unable to convert domain id to a pointer\n");
5583 return 0;
5584 }
5585 return 0;
5586 }
5587
5588 static int
debug_cmd(char * cmd,char ** toks,void * cb_data)5589 debug_cmd(char *cmd, char **toks, void *cb_data)
5590 {
5591 char *type;
5592 char *on_off;
5593 int val;
5594
5595 type = strtok_r(NULL, " \t\n", toks);
5596 if (!type) {
5597 cmd_win_out("No debug type specified\n");
5598 goto out;
5599 }
5600
5601 on_off = strtok_r(NULL, " \t\n", toks);
5602 if (!on_off) {
5603 cmd_win_out("on or off not specified\n");
5604 goto out;
5605 } else if (strcmp(on_off, "on") == 0) {
5606 val = 1;
5607 } else if (strcmp(on_off, "off") == 0) {
5608 val = 0;
5609 } else {
5610 cmd_win_out("on or off not specified, got '%s'\n", on_off);
5611 goto out;
5612 }
5613
5614 if (strcmp(type, "msg") == 0) {
5615 if (val) DEBUG_MSG_ENABLE(); else DEBUG_MSG_DISABLE();
5616 } else if (strcmp(type, "rawmsg") == 0) {
5617 if (val) DEBUG_RAWMSG_ENABLE(); else DEBUG_RAWMSG_DISABLE();
5618 } else if (strcmp(type, "locks") == 0) {
5619 if (val) DEBUG_LOCKS_ENABLE(); else DEBUG_LOCKS_DISABLE();
5620 } else if (strcmp(type, "events") == 0) {
5621 if (val) DEBUG_EVENTS_ENABLE(); else DEBUG_EVENTS_DISABLE();
5622 } else if (strcmp(type, "con0") == 0) {
5623 if (val) DEBUG_CON_FAIL_ENABLE(0); else DEBUG_CON_FAIL_DISABLE(0);
5624 } else if (strcmp(type, "con1") == 0) {
5625 if (val) DEBUG_CON_FAIL_ENABLE(1); else DEBUG_CON_FAIL_DISABLE(1);
5626 } else if (strcmp(type, "con2") == 0) {
5627 if (val) DEBUG_CON_FAIL_ENABLE(2); else DEBUG_CON_FAIL_DISABLE(2);
5628 } else if (strcmp(type, "con3") == 0) {
5629 if (val) DEBUG_CON_FAIL_ENABLE(3); else DEBUG_CON_FAIL_DISABLE(3);
5630 } else {
5631 cmd_win_out("Invalid debug type specified: '%s'\n", type);
5632 goto out;
5633 }
5634
5635 out:
5636 return 0;
5637 }
5638
5639 static void
clear_sel_cmder(ipmi_domain_t * domain,void * cb_data)5640 clear_sel_cmder(ipmi_domain_t *domain, void *cb_data)
5641 {
5642 ipmi_event_t *event, *event2;
5643
5644 event = ipmi_domain_first_event(domain);
5645 while (event) {
5646 event2 = event;
5647 event = ipmi_domain_next_event(domain, event2);
5648 ipmi_domain_del_event(domain, event2, NULL, NULL);
5649 ipmi_event_free(event2);
5650 }
5651 }
5652
5653 static int
clear_sel_cmd(char * cmd,char ** toks,void * cb_data)5654 clear_sel_cmd(char *cmd, char **toks, void *cb_data)
5655 {
5656 int rv;
5657
5658 rv = ipmi_domain_pointer_cb(domain_id, clear_sel_cmder, NULL);
5659 if (rv) {
5660 cmd_win_out("Unable to convert domain id to a pointer\n");
5661 return 0;
5662 }
5663 return 0;
5664 }
5665
5666 static void
list_sel_cmder(ipmi_domain_t * domain,void * cb_data)5667 list_sel_cmder(ipmi_domain_t *domain, void *cb_data)
5668 {
5669 int rv;
5670 ipmi_event_t *event, *event2;
5671 unsigned int count1, count2;
5672
5673 curr_display_type = EVENTS;
5674 display_pad_clear();
5675 rv = ipmi_domain_sel_count(domain, &count1);
5676 if (rv)
5677 count1 = -1;
5678 rv = ipmi_domain_sel_entries_used(domain, &count2);
5679 if (rv)
5680 count2 = -1;
5681 display_pad_out("Event counts: %d entries, %d slots used\n",
5682 count1, count2);
5683 display_pad_out("Events:\n");
5684 event = ipmi_domain_first_event(domain);
5685 while (event) {
5686 ipmi_mcid_t mcid = ipmi_event_get_mcid(event);
5687 unsigned int record_id = ipmi_event_get_record_id(event);
5688 unsigned int type = ipmi_event_get_type(event);
5689 ipmi_time_t timestamp = ipmi_event_get_timestamp(event);
5690 unsigned int data_len = ipmi_event_get_data_len(event);
5691 const unsigned char *data = ipmi_event_get_data_ptr(event);
5692 unsigned int i;
5693
5694 display_pad_out(" (%x %x) %4.4x:%2.2x %lld:",
5695 mcid.channel, mcid.mc_num, record_id, type, timestamp);
5696 for (i=0; i<data_len; i++)
5697 display_pad_out(" %2.2x", data[i]);
5698 display_pad_out("\n");
5699 event2 = ipmi_domain_next_event(domain, event);
5700 ipmi_event_free(event);
5701 event = event2;
5702 }
5703 display_pad_refresh();
5704 }
5705
5706 static int
list_sel_cmd(char * cmd,char ** toks,void * cb_data)5707 list_sel_cmd(char *cmd, char **toks, void *cb_data)
5708 {
5709 int rv;
5710
5711 rv = ipmi_domain_pointer_cb(domain_id, list_sel_cmder, NULL);
5712 if (rv) {
5713 cmd_win_out("Unable to convert domain id to a pointer\n");
5714 return 0;
5715 }
5716 return 0;
5717 }
5718
5719 void
sel_time_fetched(ipmi_mc_t * mc,int err,unsigned long time,void * cb_data)5720 sel_time_fetched(ipmi_mc_t *mc,
5721 int err,
5722 unsigned long time,
5723 void *cb_data)
5724 {
5725 if (!mc) {
5726 display_pad_out("MC went away while fetching SEL time\n");
5727 goto out;
5728 }
5729
5730 if (err) {
5731 display_pad_out("Error fetching SEL time: %x\n", err);
5732 goto out;
5733 }
5734
5735 display_pad_out("SEL time is 0x%x\n", time);
5736
5737 out:
5738 display_pad_refresh();
5739 }
5740
get_sel_time_handler(ipmi_mc_t * mc,void * cb_data)5741 void get_sel_time_handler(ipmi_mc_t *mc, void *cb_data)
5742 {
5743 mccmd_info_t *info = cb_data;
5744 int rv;
5745
5746 info->found = 1;
5747 rv = ipmi_mc_get_current_sel_time(mc, sel_time_fetched, NULL);
5748 if (rv)
5749 cmd_win_out("Error sending SEL time fetch: %x\n", rv);
5750 }
5751
5752 int
get_sel_time_cmd(char * cmd,char ** toks,void * cb_data)5753 get_sel_time_cmd(char *cmd, char **toks, void *cb_data)
5754 {
5755 mccmd_info_t info;
5756 int rv;
5757
5758 if (get_mc_id(toks, &info.mc_id))
5759 return 0;
5760
5761 info.found = 0;
5762 rv = ipmi_mc_pointer_noseq_cb(info.mc_id, get_sel_time_handler, &info);
5763 if (rv) {
5764 cmd_win_out("Unable to find MC\n");
5765 return 0;
5766 }
5767 if (!info.found) {
5768 cmd_win_out("Unable to find MC (%d %x)\n",
5769 info.mc_id.channel, info.mc_id.mc_num);
5770 }
5771 display_pad_refresh();
5772
5773 return 0;
5774 }
5775
5776 static void
mc_reset_done(ipmi_mc_t * mc,int err,void * cb_data)5777 mc_reset_done(ipmi_mc_t *mc, int err, void *cb_data)
5778 {
5779 if (err)
5780 ui_log("Error resetting mc: %x", err);
5781 else
5782 ui_log("MC reset");
5783 }
5784
5785 static void
mc_reset_handler(ipmi_mc_t * mc,void * cb_data)5786 mc_reset_handler(ipmi_mc_t *mc, void *cb_data)
5787 {
5788 mccmd_info_t *info = cb_data;
5789 int rv;
5790
5791 info->found = 1;
5792 rv = ipmi_mc_reset(mc, info->msg.cmd, mc_reset_done, NULL);
5793 if (rv)
5794 cmd_win_out("Error sending MC reset: %x\n", rv);
5795 }
5796
5797 static int
mc_reset_cmd(char * cmd,char ** toks,void * cb_data)5798 mc_reset_cmd(char *cmd, char **toks, void *cb_data)
5799 {
5800 mccmd_info_t info;
5801 int rv;
5802 char *type;
5803
5804 if (get_mc_id(toks, &info.mc_id))
5805 return 0;
5806
5807 type = strtok_r(NULL, " \n\t", toks);
5808 if (!type) {
5809 cmd_win_out("No reset type given, must be 'cold' or 'warm'\n");
5810 return 0;
5811 }
5812
5813 if (strcmp(type, "warm") == 0) {
5814 info.msg.cmd = IPMI_MC_RESET_WARM;
5815 } else if (strcmp(type, "cold") == 0) {
5816 info.msg.cmd = IPMI_MC_RESET_COLD;
5817 } else {
5818 cmd_win_out("Invalid reset type given, must be 'cold' or 'warm'\n");
5819 return 0;
5820 }
5821
5822 info.found = 0;
5823 rv = ipmi_mc_pointer_noseq_cb(info.mc_id, mc_reset_handler, &info);
5824 if (rv) {
5825 cmd_win_out("Unable to find MC\n");
5826 return 0;
5827 }
5828 if (!info.found) {
5829 cmd_win_out("Unable to find MC (%d %x)\n",
5830 info.mc_id.channel, info.mc_id.mc_num);
5831 }
5832 display_pad_refresh();
5833
5834 return 0;
5835 }
5836
5837 typedef struct sdrs_info_s
5838 {
5839 int found;
5840 ipmi_mcid_t mc_id;
5841 unsigned char do_sensors;
5842 } sdrs_info_t;
5843
sdrs_fetched(ipmi_sdr_info_t * sdrs,int err,int changed,unsigned int count,void * cb_data)5844 void sdrs_fetched(ipmi_sdr_info_t *sdrs,
5845 int err,
5846 int changed,
5847 unsigned int count,
5848 void *cb_data)
5849 {
5850 sdrs_info_t *info = cb_data;
5851 unsigned int i;
5852 int rv;
5853 int total_size = 0;
5854
5855 if (err) {
5856 ui_log("Error fetching sdrs: %x\n", err);
5857 goto out;
5858 }
5859
5860 if (!sdrs) {
5861 ui_log("sdrs went away during fetch\n");
5862 goto out;
5863 }
5864
5865 display_pad_clear();
5866 curr_display_type = DISPLAY_SDRS;
5867
5868 display_pad_out("%s SDRs for MC (%x %x)\n",
5869 info->do_sensors ? "device" : "main",
5870 info->mc_id.channel, info->mc_id.mc_num);
5871 for (i=0; i<count; i++) {
5872 ipmi_sdr_t sdr;
5873 int j;
5874
5875 rv = ipmi_get_sdr_by_index(sdrs, i, &sdr);
5876 if (rv) {
5877 display_pad_out("*could not get index %d\n", i);
5878 continue;
5879 }
5880 total_size += sdr.length+5;
5881 display_pad_out("%4.4x: type %x, version %d.%d",
5882 sdr.record_id, sdr.type, sdr.major_version, sdr.minor_version);
5883 for (j=0; j<sdr.length; j++) {
5884 if ((j % 8) == 0)
5885 display_pad_out("\n ");
5886 display_pad_out(" %2.2x", sdr.data[j]);
5887 }
5888 display_pad_out("\n");
5889 }
5890 display_pad_out("total bytes in SDRs: %d\n", total_size);
5891 display_pad_refresh();
5892
5893 out:
5894 ipmi_sdr_info_destroy(sdrs, NULL, NULL);
5895 ipmi_mem_free(info);
5896 }
5897
5898 void
start_sdr_dump(ipmi_mc_t * mc,sdrs_info_t * info)5899 start_sdr_dump(ipmi_mc_t *mc, sdrs_info_t *info)
5900 {
5901 ipmi_sdr_info_t *sdrs;
5902 int rv;
5903
5904 rv = ipmi_sdr_info_alloc(ipmi_mc_get_domain(mc),
5905 mc, 0, info->do_sensors, &sdrs);
5906 if (rv) {
5907 cmd_win_out("Unable to alloc sdr info: %x\n", rv);
5908 ipmi_mem_free(info);
5909 return;
5910 }
5911
5912 rv = ipmi_sdr_fetch(sdrs, sdrs_fetched, info);
5913 if (rv) {
5914 cmd_win_out("Unable to start SDR fetch: %x\n", rv);
5915 ipmi_sdr_info_destroy(sdrs, NULL, NULL);
5916 ipmi_mem_free(info);
5917 return;
5918 }
5919 }
5920
5921 void
sdrs_mcs_handler(ipmi_mc_t * mc,void * cb_data)5922 sdrs_mcs_handler(ipmi_mc_t *mc,
5923 void *cb_data)
5924 {
5925 sdrs_info_t *info = cb_data;
5926
5927 info->found = 1;
5928 start_sdr_dump(mc, info);
5929 }
5930
5931 static int
sdrs_cmd(char * cmd,char ** toks,void * cb_data)5932 sdrs_cmd(char *cmd, char **toks, void *cb_data)
5933 {
5934 int rv;
5935 sdrs_info_t *info;
5936
5937 info = ipmi_mem_alloc(sizeof(*info));
5938 if (!info) {
5939 ui_log("Could not allocate memory for SDR fetch\n");
5940 return 0;
5941 }
5942
5943 if (get_mc_id(toks, &info->mc_id)) {
5944 ipmi_mem_free(info);
5945 return 0;
5946 }
5947
5948 if (get_uchar(toks, &info->do_sensors, "do_sensors")) {
5949 ipmi_mem_free(info);
5950 return 0;
5951 }
5952
5953 info->found = 0;
5954
5955 rv = ipmi_mc_pointer_noseq_cb(info->mc_id, sdrs_mcs_handler, info);
5956 if (rv) {
5957 cmd_win_out("Unable to find MC\n");
5958 ipmi_mem_free(info);
5959 } else {
5960 if (!info->found) {
5961 cmd_win_out("Unable to find that mc\n");
5962 ipmi_mem_free(info);
5963 }
5964 }
5965 return 0;
5966 }
5967
5968 typedef struct scan_cmd_info_s
5969 {
5970 unsigned char addr;
5971 unsigned char channel;
5972 } scan_cmd_info_t;
5973
scan_done(ipmi_domain_t * domain,int err,void * cb_data)5974 void scan_done(ipmi_domain_t *domain, int err, void *cb_data)
5975 {
5976 log_pad_out("Bus scan done\n");
5977 }
5978
5979 static void
scan_cmder(ipmi_domain_t * domain,void * cb_data)5980 scan_cmder(ipmi_domain_t *domain, void *cb_data)
5981 {
5982 scan_cmd_info_t *info = cb_data;
5983
5984 ipmi_start_ipmb_mc_scan(domain, info->channel,
5985 info->addr, info->addr,
5986 scan_done, NULL);
5987 }
5988
5989 static int
scan_cmd(char * cmd,char ** toks,void * cb_data)5990 scan_cmd(char *cmd, char **toks, void *cb_data)
5991 {
5992 int rv;
5993 scan_cmd_info_t info;
5994
5995 if (get_uchar(toks, &info.channel, "channel"))
5996 return 0;
5997
5998 if (get_uchar(toks, &info.addr, "IPMB address"))
5999 return 0;
6000
6001 rv = ipmi_domain_pointer_cb(domain_id, scan_cmder, &info);
6002 if (rv) {
6003 cmd_win_out("Unable to convert domain id to a pointer\n");
6004 }
6005 return 0;
6006 }
6007
6008 static void
presence_cmder(ipmi_domain_t * domain,void * cb_data)6009 presence_cmder(ipmi_domain_t *domain, void *cb_data)
6010 {
6011 int rv;
6012
6013 rv = ipmi_detect_domain_presence_changes(domain, 1);
6014 if (rv)
6015 cmd_win_out("domain presence detect error: %x\n", rv);
6016 }
6017
6018 int
presence_cmd(char * cmd,char ** toks,void * cb_data)6019 presence_cmd(char *cmd, char **toks, void *cb_data)
6020 {
6021 int rv;
6022
6023 rv = ipmi_domain_pointer_cb(domain_id, presence_cmder, NULL);
6024 if (rv) {
6025 cmd_win_out("Unable to convert domain id to a pointer\n");
6026 return 0;
6027 }
6028
6029 return 0;
6030 }
6031
6032 static void
is_con_active_cmder(ipmi_domain_t * domain,void * cb_data)6033 is_con_active_cmder(ipmi_domain_t *domain, void *cb_data)
6034 {
6035 int rv;
6036 unsigned int *connection = cb_data;
6037 unsigned int val;
6038
6039 rv = ipmi_domain_is_connection_active(domain, *connection, &val);
6040 if (rv)
6041 cmd_win_out("Invalid connection number %d: %x\n", *connection, rv);
6042 else
6043 cmd_win_out("Connection %d is%s active\n",
6044 *connection, val ? "" : " not");
6045 }
6046
6047 static int
is_con_active_cmd(char * cmd,char ** toks,void * cb_data)6048 is_con_active_cmd(char *cmd, char **toks, void *cb_data)
6049 {
6050 int rv;
6051 unsigned int connection;
6052
6053 if (get_uint(toks, &connection, "connection"))
6054 return 0;
6055
6056 rv = ipmi_domain_pointer_cb(domain_id, is_con_active_cmder, &connection);
6057 if (rv) {
6058 cmd_win_out("Unable to convert domain id to a pointer\n");
6059 return 0;
6060 }
6061
6062 return 0;
6063 }
6064
6065 static void
activate_con_cmder(ipmi_domain_t * domain,void * cb_data)6066 activate_con_cmder(ipmi_domain_t *domain, void *cb_data)
6067 {
6068 int rv;
6069 unsigned int *connection = cb_data;
6070
6071 rv = ipmi_domain_activate_connection(domain, *connection);
6072 if (rv)
6073 cmd_win_out("Invalid connection number %d: %x\n", *connection, rv);
6074 }
6075
6076 static int
activate_con_cmd(char * cmd,char ** toks,void * cb_data)6077 activate_con_cmd(char *cmd, char **toks, void *cb_data)
6078 {
6079 int rv;
6080 unsigned int connection;
6081
6082 if (get_uint(toks, &connection, "connection"))
6083 return 0;
6084
6085 rv = ipmi_domain_pointer_cb(domain_id, activate_con_cmder, &connection);
6086 if (rv) {
6087 cmd_win_out("Unable to convert domain id to a pointer\n");
6088 return 0;
6089 }
6090
6091 return 0;
6092 }
6093
6094 static int
quit_cmd(char * cmd,char ** toks,void * cb_data)6095 quit_cmd(char *cmd, char **toks, void *cb_data)
6096 {
6097 int rv;
6098
6099 rv = ipmi_domain_pointer_cb(domain_id, leave_cmder, NULL);
6100 if (rv) {
6101 leave(0, "");
6102 }
6103 return 0;
6104 }
6105
6106 static int
display_win_cmd(char * cmd,char ** toks,void * cb_data)6107 display_win_cmd(char *cmd, char **toks, void *cb_data)
6108 {
6109 curr_win = DISPLAY_WIN_SCROLL;
6110 return 0;
6111 }
6112
6113 static int
log_win_cmd(char * cmd,char ** toks,void * cb_data)6114 log_win_cmd(char *cmd, char **toks, void *cb_data)
6115 {
6116 curr_win = LOG_WIN_SCROLL;
6117 return 0;
6118 }
6119
6120 static int
new_domain_cmd(char * cmd,char ** toks,void * cb_data)6121 new_domain_cmd(char *cmd, char **toks, void *cb_data)
6122 {
6123 char *parms[30];
6124 int num_parms;
6125 int curr_parm;
6126 ipmi_args_t *con_parms[2];
6127 int set = 0;
6128 int i;
6129 ipmi_con_t *con[2];
6130 int rv;
6131
6132 for (num_parms=0; num_parms<30; num_parms++) {
6133 parms[num_parms] = strtok_r(NULL, " \t\n", toks);
6134 if (!parms[num_parms])
6135 break;
6136 /* Remove surrounding quotes, if any. */
6137 if (parms[num_parms][0] == '"') {
6138 (parms[num_parms])++;
6139 if (parms[num_parms][0])
6140 parms[num_parms][strlen(parms[num_parms])-1] = '\0';
6141 }
6142 }
6143
6144 if (num_parms < 2) {
6145 cmd_win_out("Not enough parms given\n");
6146 return 0;
6147 }
6148
6149 curr_parm = 1;
6150 rv = ipmi_parse_args(&curr_parm, num_parms, parms, &con_parms[set]);
6151 if (rv) {
6152 cmd_win_out("First connection parms are invalid\n");
6153 return 0;
6154 }
6155 set++;
6156
6157 if (curr_parm > num_parms) {
6158 rv = ipmi_parse_args(&curr_parm, num_parms, parms, &con_parms[set]);
6159 if (rv) {
6160 ipmi_free_args(con_parms[0]);
6161 cmd_win_out("Second connection parms are invalid\n");
6162 goto out;
6163 }
6164 set++;
6165 }
6166
6167 for (i=0; i<set; i++) {
6168 rv = ipmi_args_setup_con(con_parms[i],
6169 ipmi_ui_os_hnd,
6170 NULL,
6171 &con[i]);
6172 if (rv) {
6173 cmd_win_out("ipmi_ip_setup_con: %s\n", strerror(rv));
6174 goto out;
6175 }
6176 }
6177
6178 rv = ipmi_open_domain(parms[0], con, set, ipmi_ui_setup_done,
6179 NULL, NULL, NULL, NULL, 0, NULL);
6180 if (rv) {
6181 cmd_win_out("ipmi_open_domain: %s\n", strerror(rv));
6182 for (i=0; i<set; i++)
6183 con[i]->close_connection(con[i]);
6184 goto out;
6185 }
6186
6187 cmd_win_out("Domain started\n");
6188 out:
6189 for (i=0; i<set; i++)
6190 ipmi_free_args(con_parms[i]);
6191
6192 return 0;
6193
6194 }
6195
6196 static void
final_close(void * cb_data)6197 final_close(void *cb_data)
6198 {
6199 ui_log("Domain close");
6200 }
6201
6202 typedef struct domain_scan_s
6203 {
6204 int err;
6205 char *name;
6206 } domain_scan_t;
6207
6208 static void
close_domain_handler(ipmi_domain_t * domain,void * cb_data)6209 close_domain_handler(ipmi_domain_t *domain, void *cb_data)
6210 {
6211 domain_scan_t *info = cb_data;
6212 char name[IPMI_DOMAIN_NAME_LEN];
6213
6214 ipmi_domain_get_name(domain, name, sizeof(name));
6215 if (strcmp(name, info->name) == 0) {
6216 /* Found it. */
6217 info->err = ipmi_domain_close(domain, final_close, NULL);
6218 if (info->err)
6219 cmd_win_out("Could not close connection\n");
6220 }
6221 }
6222
6223
6224 static int
close_domain_cmd(char * cmd,char ** toks,void * cb_data)6225 close_domain_cmd(char *cmd, char **toks, void *cb_data)
6226 {
6227 domain_scan_t info;
6228
6229 info.err = ENODEV;
6230 info.name = strtok_r(NULL, " \t\n", toks);
6231 if (!info.name) {
6232 cmd_win_out("No domain given\n");
6233 return 0;
6234 }
6235
6236 ipmi_domain_iterate_domains(close_domain_handler, &info);
6237
6238 return 0;
6239 }
6240
6241 static void
set_domain_handler(ipmi_domain_t * domain,void * cb_data)6242 set_domain_handler(ipmi_domain_t *domain, void *cb_data)
6243 {
6244 domain_scan_t *info = cb_data;
6245 char name[IPMI_DOMAIN_NAME_LEN];
6246
6247 ipmi_domain_get_name(domain, name, sizeof(name));
6248 if (strcmp(name, info->name) == 0) {
6249 /* Found it. */
6250 info->err = 0;
6251 domain_id = ipmi_domain_convert_to_id(domain);
6252 }
6253 }
6254
6255 static int
set_domain_cmd(char * cmd,char ** toks,void * cb_data)6256 set_domain_cmd(char *cmd, char **toks, void *cb_data)
6257 {
6258 domain_scan_t info;
6259
6260 info.err = ENODEV;
6261 info.name = strtok_r(NULL, " \t\n", toks);
6262 if (!info.name) {
6263 cmd_win_out("No domain given\n");
6264 return 0;
6265 }
6266
6267 ipmi_domain_iterate_domains(set_domain_handler, &info);
6268 if (info.err)
6269 cmd_win_out("Error setting domain: 0x%x\n", info.err);
6270
6271 return 0;
6272 }
6273
6274 static void
domains_handler(ipmi_domain_t * domain,void * cb_data)6275 domains_handler(ipmi_domain_t *domain, void *cb_data)
6276 {
6277 char name[IPMI_DOMAIN_NAME_LEN];
6278
6279 ipmi_domain_get_name(domain, name, sizeof(name));
6280 display_pad_out(" %s\n", name);
6281 }
6282
6283 static int
domains_cmd(char * cmd,char ** toks,void * cb_data)6284 domains_cmd(char *cmd, char **toks, void *cb_data)
6285 {
6286 display_pad_clear();
6287 display_pad_out("Domains:\n");
6288 ipmi_domain_iterate_domains(domains_handler, NULL);
6289 display_pad_refresh();
6290
6291 return 0;
6292 }
6293
6294 static int help_cmd(char *cmd, char **toks, void *cb_data);
6295
6296 static struct {
6297 char *name;
6298 cmd_handler_t handler;
6299 char *help;
6300 } cmd_list[] =
6301 {
6302 { "display_win", display_win_cmd,
6303 " - Sets the display window (left window) for scrolling" },
6304 { "log_win", log_win_cmd,
6305 " - Sets the log window (right window) for scrolling" },
6306 { "entities", entities_cmd,
6307 " - list all the entities the UI knows about" },
6308 { "entity", entity_cmd,
6309 " <entity name> - list all the info about an entity" },
6310 { "hs_get_act_time", hs_get_act_time,
6311 " <entity name>"
6312 " - Get the host-swap auto-activate time" },
6313 { "hs_set_act_time", hs_set_act_time,
6314 " <entity name> <time in nanoseconds>"
6315 " - Set the host-swap auto-activate time" },
6316 { "hs_get_deact_time", hs_get_deact_time,
6317 " <entity name>"
6318 " - Get the host-swap auto-deactivate time" },
6319 { "hs_set_deact_time", hs_set_deact_time,
6320 " <entity name> <time in nanoseconds>"
6321 " - Set the host-swap auto-deactivate time" },
6322 { "hs_activation_request", hs_activation_request,
6323 " <entity name> - Act like a user requested an activation of the"
6324 " entity. This is generally equivalent to closing the handle"
6325 " latch or something like that." },
6326 { "hs_activate", hs_activate,
6327 " <entity name> - activate the given entity" },
6328 { "hs_deactivate", hs_deactivate,
6329 " <entity name> - deactivate the given entity" },
6330 { "hs_state", hs_state,
6331 " <entity name> - Return the current hot-swap state" },
6332 { "hs_check", hs_check_cmd,
6333 " - Check all the entities hot-swap states" },
6334 { "sensors", sensors_cmd,
6335 " <entity name> - list all the sensors that monitor the entity" },
6336 { "sensor", sensor_cmd,
6337 " <sensor name> - Pull up all the information on the sensor and start"
6338 " monitoring it" },
6339 { "fru", fru_cmd,
6340 " <entity name> - dump fru information" },
6341 { "dump_fru", dump_fru_cmd,
6342 " <is_logical> <device_address> <device_id> <lun> <private_bus>"
6343 " <channel> - dump a fru given all it's insundry information" },
6344 { "rearm", rearm_cmd,
6345 " - rearm the current sensor" },
6346 { "set_hysteresis", set_hysteresis_cmd,
6347 " <val> - Sets the hysteresis for the current sensor" },
6348 { "get_hysteresis", get_hysteresis_cmd,
6349 " - Gets the hysteresis for the current sensor" },
6350 { "controls", controls_cmd,
6351 " <entity name> - list all the controls attached to the entity" },
6352 { "control", control_cmd,
6353 " <control name> - Pull up all the information on the control and start"
6354 " monitoring it" },
6355 { "set_control", set_control_cmd,
6356 " <val1> [<val2> ...] - set the value(s) for the control" },
6357 { "mcs", mcs_cmd,
6358 " - List all the management controllers in the system. They"
6359 " are listed (<channel>, <mc num>)" },
6360 { "mc", mc_cmd,
6361 " <channel> <mc num>"
6362 " - Dump info on the given MC"},
6363 { "mc_reset", mc_reset_cmd,
6364 " <channel> <mc num> [warm | cold]"
6365 " - Do a warm or cold reset on the given MC"},
6366 { "mccmd", mccmd_cmd,
6367 " <channel> <mc num> <LUN> <NetFN> <Cmd> [data...]"
6368 " - Send the given command"
6369 " to the management controller and display the response" },
6370 { "mc_events_enable", mc_events_enable_cmd,
6371 " <channel> <mc num> <enabled> - set enabled to 0 to disable events,"
6372 " 1 to enable them. This is the global event enable on the MC." },
6373 { "mc_events_enabled", mc_events_enabled_cmd,
6374 " <channel> <mc num> - Prints out if the events are enabled for"
6375 " the given MC." },
6376 { "msg", msg_cmd,
6377 " <channel> <IPMB addr> <LUN> <NetFN> <Cmd> [data...] - Send a command"
6378 " to the given IPMB address on the given channel and display the"
6379 " response" },
6380 { "readpef", readpef_cmd,
6381 " <channel> <mc num>"
6382 " - read pef information from an MC" },
6383 { "clearpeflock", clearpeflock_cmd,
6384 " [<channel> <mc num>]"
6385 " - Clear a PEF lock. If the MC is given, then the PEF is directly"
6386 " cleared. If not given, then the current PEF is cleared" },
6387 { "viewpef", viewpef_cmd,
6388 " - show current pef information " },
6389 { "writepef", writepef_cmd,
6390 " <channel> <mc num>"
6391 " - write the current PEF information to an MC" },
6392 { "setpef", setpef_cmd,
6393 " <config> [<selector>] <value>"
6394 " - Set the given config item to the value. The optional selector"
6395 " is used for items that take a selector" },
6396 { "readlanparm", readlanparm_cmd,
6397 " <channel> <mc num> <channel>"
6398 " - read lanparm information from an MC" },
6399 { "viewlanparm", viewlanparm_cmd,
6400 " - show current lanparm information " },
6401 { "writelanparm", writelanparm_cmd,
6402 " <channel> <mc num> <channel>"
6403 " - write the current LANPARM information to an MC" },
6404 { "clearlanparmlock", clearlanparmlock_cmd,
6405 " [<channel> <mc num> <channel>]"
6406 " - Clear a LANPARM lock. If the MC is given, then the LANPARM is"
6407 " directly"
6408 " cleared. If not given, then the current LANPARM is cleared" },
6409 { "setlanparm", setlanparm_cmd,
6410 " <config> [<selector>] <value>"
6411 " - Set the given config item to the value. The optional selector"
6412 " is used for items that take a selector" },
6413 { "pet", pet_cmd,
6414 " <connection> <channel> <ip addr> <mac_addr> <eft selector>"
6415 " <policy num> <apt selector>"
6416 " <lan dest selector> - "
6417 "Set up the domain to send PET traps from the given connection"
6418 " to the given IP/MAC address over the given channel" },
6419 { "delevent", delevent_cmd,
6420 " <channel> <mc num> <log number> - "
6421 "Delete the given event number from the SEL" },
6422 { "addevent", addevent_cmd,
6423 " <channel> <mc num> <record id> <type> <13 bytes of data> - "
6424 "Add the event data to the SEL" },
6425 { "debug", debug_cmd,
6426 " <type> on|off - Turn the given debugging type on or off." },
6427 { "clear_sel", clear_sel_cmd,
6428 " - clear the system event log" },
6429 { "list_sel", list_sel_cmd,
6430 " - list the local copy of the system event log" },
6431 { "get_sel_time", get_sel_time_cmd,
6432 " <channel> <mc num> - Get the time in the SEL for the given MC" },
6433 { "sdrs", sdrs_cmd,
6434 " <channel> <mc num> <do_sensors> - list the SDRs for the mc."
6435 " If do_sensors is"
6436 " 1, then the device SDRs are fetched. Otherwise the main SDRs are"
6437 " fetched." },
6438 { "events_enable", events_enable_cmd,
6439 " <events> <scanning> <assertion bitmask> <deassertion bitmask>"
6440 " - set the events enable data for the sensor" },
6441 { "scan", scan_cmd,
6442 " <ipmb addr> - scan an IPMB to add or remove it" },
6443 { "is_con_active", is_con_active_cmd,
6444 " <connection> - print out if the given connection is active or not" },
6445 { "activate_con", activate_con_cmd,
6446 " <connection> - Activate the given connection" },
6447 { "quit", quit_cmd,
6448 " - leave the program" },
6449 { "check_presence", presence_cmd,
6450 " - Check the presence of entities" },
6451 { "new_domain", new_domain_cmd,
6452 " <domain name> <parms...> - Open a connection to a new domain" },
6453 { "close_domain", close_domain_cmd,
6454 " <num> - close the given domain number" },
6455 { "set_domain", set_domain_cmd,
6456 " <num> - Use the given domain number" },
6457 { "domains", domains_cmd,
6458 " - List all the domains" },
6459 { "help", help_cmd,
6460 " - This output"},
6461 { NULL, NULL}
6462 };
6463 int
init_commands(void)6464 init_commands(void)
6465 {
6466 int err;
6467 int i;
6468
6469 commands = command_alloc();
6470 if (!commands)
6471 return ENOMEM;
6472
6473 for (i=0; cmd_list[i].name != NULL; i++) {
6474 err = command_bind(commands, cmd_list[i].name, cmd_list[i].handler);
6475 if (err)
6476 goto out_err;
6477 }
6478
6479 return 0;
6480
6481 out_err:
6482 command_free(commands);
6483 return err;
6484 }
6485
6486 static int
help_cmd(char * cmd,char ** toks,void * cb_data)6487 help_cmd(char *cmd, char **toks, void *cb_data)
6488 {
6489 int i;
6490
6491 display_pad_clear();
6492 curr_display_type = HELP;
6493 display_pad_out("Welcome to the IPMI UI version %s\n", OPENIPMI_VERSION);
6494 for (i=0; cmd_list[i].name != NULL; i++) {
6495 display_pad_out(" %s%s\n", cmd_list[i].name, cmd_list[i].help);
6496 }
6497 display_pad_refresh();
6498
6499 return 0;
6500 }
6501
6502 int
init_keypad(void)6503 init_keypad(void)
6504 {
6505 int i;
6506 int err = 0;
6507
6508 keymap = keypad_alloc();
6509 if (!keymap)
6510 return ENOMEM;
6511
6512 for (i=0x20; i<0x7f; i++) {
6513 err = keypad_bind_key(keymap, i, normal_char);
6514 if (err)
6515 goto out_err;
6516 }
6517
6518 err = keypad_bind_key(keymap, 0x7f, backspace);
6519 if (!err)
6520 err = keypad_bind_key(keymap, 9, normal_char);
6521 if (!err)
6522 err = keypad_bind_key(keymap, 8, backspace);
6523 if (!err)
6524 err = keypad_bind_key(keymap, 4, key_leave);
6525 if (!err)
6526 err = keypad_bind_key(keymap, 10, end_of_line);
6527 if (!err)
6528 err = keypad_bind_key(keymap, 13, end_of_line);
6529 if (full_screen) {
6530 if (!err)
6531 err = keypad_bind_key(keymap, KEY_BACKSPACE, backspace);
6532 if (!err)
6533 err = keypad_bind_key(keymap, KEY_DC, backspace);
6534 if (!err)
6535 err = keypad_bind_key(keymap, KEY_UP, key_up);
6536 if (!err)
6537 err = keypad_bind_key(keymap, KEY_DOWN, key_down);
6538 if (!err)
6539 err = keypad_bind_key(keymap, KEY_RIGHT, key_right);
6540 if (!err)
6541 err = keypad_bind_key(keymap, KEY_LEFT, key_left);
6542 if (!err)
6543 err = keypad_bind_key(keymap, KEY_NPAGE, key_npage);
6544 if (!err)
6545 err = keypad_bind_key(keymap, KEY_PPAGE, key_ppage);
6546 #ifdef HAVE_WRESIZE
6547 if (!err)
6548 err = keypad_bind_key(keymap, KEY_RESIZE, key_resize);
6549 #endif
6550 if (!err)
6551 err = keypad_bind_key(keymap, KEY_F(1), key_set_display);
6552 if (!err)
6553 err = keypad_bind_key(keymap, KEY_F(2), key_set_log);
6554 } else {
6555 if (!err)
6556 err = keypad_bind_key(keymap, -1, key_leave);
6557 }
6558 if (err)
6559 goto out_err;
6560
6561 return 0;
6562
6563 out_err:
6564 keypad_free(keymap);
6565 return err;
6566 }
6567
6568 int
init_win(void)6569 init_win(void)
6570 {
6571 main_win = initscr();
6572 if (!main_win)
6573 exit(1);
6574
6575 raw();
6576 noecho();
6577
6578 stat_win = newwin(STATUS_WIN_LINES, STATUS_WIN_COLS,
6579 STATUS_WIN_TOP, STATUS_WIN_LEFT);
6580 if (!stat_win)
6581 leave(1, "Could not allocate stat window\n");
6582
6583 display_pad = newpad(NUM_DISPLAY_LINES, DISPLAY_WIN_COLS);
6584 if (!display_pad)
6585 leave(1, "Could not allocate display window\n");
6586
6587 log_pad = newpad(NUM_LOG_LINES, LOG_WIN_COLS);
6588 if (!log_pad)
6589 leave(1, "Could not allocate log window\n");
6590 scrollok(log_pad, TRUE);
6591 wmove(log_pad, NUM_LOG_LINES-1, 0);
6592 log_pad_top_line = NUM_LOG_LINES-LOG_WIN_LINES;
6593
6594 dummy_pad = newpad(NUM_LOG_LINES, LOG_WIN_COLS);
6595 if (!dummy_pad)
6596 leave(1, "Could not allocate dummy pad\n");
6597 wmove(dummy_pad, 0, 0);
6598
6599 cmd_win = newwin(CMD_WIN_LINES, CMD_WIN_COLS, CMD_WIN_TOP, CMD_WIN_LEFT);
6600 if (!cmd_win)
6601 leave(1, "Could not allocate command window\n");
6602
6603 keypad(cmd_win, TRUE);
6604 meta(cmd_win, TRUE);
6605 nodelay(cmd_win, TRUE);
6606 scrollok(cmd_win, TRUE);
6607
6608 draw_lines();
6609
6610 display_pad_refresh();
6611
6612 cmd_win_out("> ");
6613 cmd_win_refresh();
6614
6615 return 0;
6616 }
6617
6618 static void
report_error(char * str,int err)6619 report_error(char *str, int err)
6620 {
6621 if (IPMI_IS_OS_ERR(err)) {
6622 ui_log("%s: %s\n", str, strerror(IPMI_GET_OS_ERR(err)));
6623 } else {
6624 ui_log("%s: IPMI Error %2.2x\n",
6625 str, IPMI_GET_IPMI_ERR(err));
6626 }
6627 }
6628
6629 static int
sensor_threshold_event_handler(ipmi_sensor_t * sensor,enum ipmi_event_dir_e dir,enum ipmi_thresh_e threshold,enum ipmi_event_value_dir_e high_low,enum ipmi_value_present_e value_present,unsigned int raw_value,double value,void * cb_data,ipmi_event_t * event)6630 sensor_threshold_event_handler(ipmi_sensor_t *sensor,
6631 enum ipmi_event_dir_e dir,
6632 enum ipmi_thresh_e threshold,
6633 enum ipmi_event_value_dir_e high_low,
6634 enum ipmi_value_present_e value_present,
6635 unsigned int raw_value,
6636 double value,
6637 void *cb_data,
6638 ipmi_event_t *event)
6639 {
6640 ipmi_entity_t *entity = ipmi_sensor_get_entity(sensor);
6641 char loc[MAX_ENTITY_LOC_SIZE];
6642 char name[33];
6643
6644 ipmi_sensor_get_id(sensor, name, 33);
6645 ui_log("Sensor %s.%s: %s %s %s\n",
6646 get_entity_loc(entity, loc, sizeof(loc)),
6647 name,
6648 ipmi_get_threshold_string(threshold),
6649 ipmi_get_value_dir_string(high_low),
6650 ipmi_get_event_dir_string(dir));
6651 if (value_present == IPMI_BOTH_VALUES_PRESENT) {
6652 ui_log(" value is %f (%2.2x)\n", value, raw_value);
6653 } else if (value_present == IPMI_RAW_VALUE_PRESENT) {
6654 ui_log(" raw value is 0x%x\n", raw_value);
6655 }
6656 if (event)
6657 ui_log("Due to event 0x%4.4x\n", ipmi_event_get_record_id(event));
6658 return IPMI_EVENT_NOT_HANDLED;
6659 }
6660
6661 static int
sensor_discrete_event_handler(ipmi_sensor_t * sensor,enum ipmi_event_dir_e dir,int offset,int severity,int prev_severity,void * cb_data,ipmi_event_t * event)6662 sensor_discrete_event_handler(ipmi_sensor_t *sensor,
6663 enum ipmi_event_dir_e dir,
6664 int offset,
6665 int severity,
6666 int prev_severity,
6667 void *cb_data,
6668 ipmi_event_t *event)
6669 {
6670 ipmi_entity_t *entity = ipmi_sensor_get_entity(sensor);
6671 char loc[MAX_ENTITY_LOC_SIZE];
6672 char name[33];
6673
6674 ipmi_sensor_get_id(sensor, name, 33);
6675 ui_log("Sensor %s.%s: %d %s\n",
6676 get_entity_loc(entity, loc, sizeof(loc)),
6677 name,
6678 offset,
6679 ipmi_get_event_dir_string(dir));
6680 if (severity != -1)
6681 ui_log(" severity is %d\n", severity);
6682 if (prev_severity != -1)
6683 ui_log(" prev severity is %d\n", prev_severity);
6684 if (event)
6685 ui_log("Due to event 0x%4.4x\n", ipmi_event_get_record_id(event));
6686 return IPMI_EVENT_NOT_HANDLED;
6687 }
6688
6689 static void
sensor_change(enum ipmi_update_e op,ipmi_entity_t * ent,ipmi_sensor_t * sensor,void * cb_data)6690 sensor_change(enum ipmi_update_e op,
6691 ipmi_entity_t *ent,
6692 ipmi_sensor_t *sensor,
6693 void *cb_data)
6694 {
6695 ipmi_entity_t *entity = ipmi_sensor_get_entity(sensor);
6696 char loc[MAX_ENTITY_LOC_SIZE];
6697 char name[33];
6698 char name2[33];
6699 int rv;
6700
6701 ipmi_sensor_get_id(sensor, name, 32);
6702 strcpy(name2, name);
6703 conv_from_spaces(name2);
6704 switch (op) {
6705 case IPMI_ADDED:
6706 ui_log("Sensor added: %s.%s (%s)\n",
6707 get_entity_loc(entity, loc, sizeof(loc)),
6708 name2, name);
6709 if (ipmi_sensor_get_event_reading_type(sensor)
6710 == IPMI_EVENT_READING_TYPE_THRESHOLD)
6711 rv = ipmi_sensor_add_threshold_event_handler(
6712 sensor,
6713 sensor_threshold_event_handler,
6714 NULL);
6715 else
6716 rv = ipmi_sensor_add_discrete_event_handler(
6717 sensor,
6718 sensor_discrete_event_handler,
6719 NULL);
6720 if (rv)
6721 ui_log("Unable to register sensor event handler: 0x%x\n", rv);
6722 break;
6723 case IPMI_DELETED:
6724 ui_log("Sensor deleted: %s.%s (%s)\n",
6725 get_entity_loc(entity, loc, sizeof(loc)),
6726 name2, name);
6727 break;
6728 case IPMI_CHANGED:
6729 ui_log("Sensor changed: %s.%s (%s)\n",
6730 get_entity_loc(entity, loc, sizeof(loc)),
6731 name2, name);
6732 break;
6733 }
6734 }
6735
6736 static void
control_change(enum ipmi_update_e op,ipmi_entity_t * ent,ipmi_control_t * control,void * cb_data)6737 control_change(enum ipmi_update_e op,
6738 ipmi_entity_t *ent,
6739 ipmi_control_t *control,
6740 void *cb_data)
6741 {
6742 ipmi_entity_t *entity = ipmi_control_get_entity(control);
6743 char loc[MAX_ENTITY_LOC_SIZE];
6744 char name[33];
6745 char name2[33];
6746
6747 ipmi_control_get_id(control, name, 32);
6748 strcpy(name2, name);
6749 conv_from_spaces(name2);
6750 switch (op) {
6751 case IPMI_ADDED:
6752 ui_log("Control added: %s.%s (%s)\n",
6753 get_entity_loc(entity, loc, sizeof(loc)),
6754 name2, name);
6755 break;
6756 case IPMI_DELETED:
6757 ui_log("Control deleted: %s.%s (%s)\n",
6758 get_entity_loc(entity, loc, sizeof(loc)),
6759 name2, name);
6760 break;
6761 case IPMI_CHANGED:
6762 ui_log("Control changed: %s.%s (%s)\n",
6763 get_entity_loc(entity, loc, sizeof(loc)),
6764 name2, name);
6765 break;
6766 }
6767 }
6768
6769 static int
entity_presence_handler(ipmi_entity_t * entity,int present,void * cb_data,ipmi_event_t * event)6770 entity_presence_handler(ipmi_entity_t *entity,
6771 int present,
6772 void *cb_data,
6773 ipmi_event_t *event)
6774 {
6775 char loc[MAX_ENTITY_LOC_SIZE];
6776
6777 ui_log("Entity %s, presence is %d\n",
6778 get_entity_loc(entity, loc, sizeof(loc)),
6779 present);
6780 if (event)
6781 ui_log("Due to event 0x%4.4x\n", ipmi_event_get_record_id(event));
6782 return IPMI_EVENT_NOT_HANDLED;
6783 }
6784
fru_change(enum ipmi_update_e op,ipmi_entity_t * entity,void * cb_data)6785 void fru_change(enum ipmi_update_e op,
6786 ipmi_entity_t *entity,
6787 void *cb_data)
6788 {
6789 char loc[MAX_ENTITY_LOC_SIZE];
6790
6791 switch (op) {
6792 case IPMI_ADDED:
6793 ui_log("FRU added for %s\n",
6794 get_entity_loc(entity, loc, sizeof(loc)));
6795 break;
6796 case IPMI_DELETED:
6797 ui_log("FRU deleted for %s\n",
6798 get_entity_loc(entity, loc, sizeof(loc)));
6799 break;
6800 case IPMI_CHANGED:
6801 ui_log("FRU changed for %s\n",
6802 get_entity_loc(entity, loc, sizeof(loc)));
6803 break;
6804 }
6805 }
6806
6807 static int
entity_hot_swap_handler(ipmi_entity_t * ent,enum ipmi_hot_swap_states last_state,enum ipmi_hot_swap_states curr_state,void * cb_data,ipmi_event_t * event)6808 entity_hot_swap_handler(ipmi_entity_t *ent,
6809 enum ipmi_hot_swap_states last_state,
6810 enum ipmi_hot_swap_states curr_state,
6811 void *cb_data,
6812 ipmi_event_t *event)
6813 {
6814 char loc[MAX_ENTITY_LOC_SIZE];
6815
6816 ui_log("Entity hot swap state changed for %s, was %s, now %s\n",
6817 get_entity_loc(ent, loc, sizeof(loc)),
6818 ipmi_hot_swap_state_name(last_state),
6819 ipmi_hot_swap_state_name(curr_state));
6820 return IPMI_EVENT_NOT_HANDLED;
6821 }
6822
6823 static void
entity_change(enum ipmi_update_e op,ipmi_domain_t * domain,ipmi_entity_t * entity,void * cb_data)6824 entity_change(enum ipmi_update_e op,
6825 ipmi_domain_t *domain,
6826 ipmi_entity_t *entity,
6827 void *cb_data)
6828 {
6829 int rv;
6830 char loc[MAX_ENTITY_LOC_SIZE];
6831
6832 switch (op) {
6833 case IPMI_ADDED:
6834 ui_log("Entity added: %s\n",
6835 get_entity_loc(entity, loc, sizeof(loc)));
6836 rv = ipmi_entity_add_sensor_update_handler(entity,
6837 sensor_change,
6838 entity);
6839 if (rv) {
6840 report_error("ipmi_entity_add_sensor_update_handler", rv);
6841 break;
6842 }
6843 rv = ipmi_entity_add_control_update_handler(entity,
6844 control_change,
6845 entity);
6846 if (rv) {
6847 report_error("ipmi_entity_add_control_update_handler", rv);
6848 break;
6849 }
6850 rv = ipmi_entity_add_fru_update_handler(entity,
6851 fru_change,
6852 entity);
6853 if (rv) {
6854 report_error("ipmi_entity_add_control_fru_handler", rv);
6855 break;
6856 }
6857 rv = ipmi_entity_add_presence_handler(entity,
6858 entity_presence_handler,
6859 NULL);
6860 if (rv) {
6861 report_error("ipmi_entity_add_presence_handler", rv);
6862 }
6863 rv = ipmi_entity_add_hot_swap_handler(entity,
6864 entity_hot_swap_handler,
6865 NULL);
6866 if (rv) {
6867 report_error("ipmi_entity_add_hot_swap_handler", rv);
6868 }
6869 break;
6870 case IPMI_DELETED:
6871 ui_log("Entity deleted: %s\n",
6872 get_entity_loc(entity, loc, sizeof(loc)));
6873 break;
6874 case IPMI_CHANGED:
6875 ui_log("Entity changed: %s\n",
6876 get_entity_loc(entity, loc, sizeof(loc)));
6877 break;
6878 }
6879
6880 if (ipmi_entity_hot_swappable(entity))
6881 ui_log("Entity is hot swappable\n");
6882 else
6883 ui_log("Entity is not hot swappable\n");
6884 }
6885
6886 static void
mc_sels_read(ipmi_mc_t * mc,void * cb_data)6887 mc_sels_read(ipmi_mc_t *mc, void *cb_data)
6888 {
6889 int addr = ipmi_mc_get_address(mc);
6890 int channel = ipmi_mc_get_channel(mc);
6891
6892 ui_log("MC (%d %x) SELs read\n", channel, addr);
6893 }
6894
6895 static void
mc_sdrs_read(ipmi_mc_t * mc,void * cb_data)6896 mc_sdrs_read(ipmi_mc_t *mc, void *cb_data)
6897 {
6898 int addr = ipmi_mc_get_address(mc);
6899 int channel = ipmi_mc_get_channel(mc);
6900
6901 ui_log("MC (%d %x) SDRs read\n", channel, addr);
6902 }
6903
6904 static void
mc_active(ipmi_mc_t * mc,int active,void * cb_data)6905 mc_active(ipmi_mc_t *mc, int active, void *cb_data)
6906 {
6907 int addr = ipmi_mc_get_address(mc);
6908 int channel = ipmi_mc_get_channel(mc);
6909
6910 ui_log("MC is %s: (%d %x)\n",
6911 active ? "active" : "inactive",
6912 channel, addr);
6913 ipmi_mc_set_sdrs_first_read_handler(mc, mc_sdrs_read, NULL);
6914 ipmi_mc_set_sels_first_read_handler(mc, mc_sels_read, NULL);
6915 }
6916
6917 static void
mc_change(enum ipmi_update_e op,ipmi_domain_t * domain,ipmi_mc_t * mc,void * cb_data)6918 mc_change(enum ipmi_update_e op,
6919 ipmi_domain_t *domain,
6920 ipmi_mc_t *mc,
6921 void *cb_data)
6922 {
6923 int addr = ipmi_mc_get_address(mc);
6924 int channel = ipmi_mc_get_channel(mc);
6925 int rv;
6926
6927 switch (op) {
6928 case IPMI_ADDED:
6929 rv = ipmi_mc_add_active_handler(mc, mc_active, NULL);
6930 if (rv)
6931 ui_log("Unable to add MC active handler: 0x%x\n", rv);
6932 if (ipmi_mc_is_active(mc)) {
6933 ipmi_mc_set_sdrs_first_read_handler(mc, mc_sdrs_read, NULL);
6934 ipmi_mc_set_sels_first_read_handler(mc, mc_sels_read, NULL);
6935 ui_log("MC added: (%d %x) - (active)\n", channel, addr);
6936 } else {
6937 ui_log("MC added: (%d %x) - (inactive)\n", channel, addr);
6938 }
6939 break;
6940 case IPMI_DELETED:
6941 ui_log("MC deleted: (%d %x)\n", channel, addr);
6942 break;
6943 case IPMI_CHANGED:
6944 ui_log("MC changed: (%d %x)\n", channel, addr);
6945 break;
6946 }
6947 }
6948
6949 static void
event_handler(ipmi_domain_t * domain,ipmi_event_t * event,void * event_data)6950 event_handler(ipmi_domain_t *domain,
6951 ipmi_event_t *event,
6952 void *event_data)
6953 {
6954 ipmi_mcid_t mcid = ipmi_event_get_mcid(event);
6955 unsigned int record_id = ipmi_event_get_record_id(event);
6956 unsigned int type = ipmi_event_get_type(event);
6957 ipmi_time_t timestamp = ipmi_event_get_timestamp(event);
6958 unsigned int data_len = ipmi_event_get_data_len(event);
6959 const unsigned char *data = ipmi_event_get_data_ptr(event);
6960 unsigned int i;
6961 char str[200];
6962 int pos;
6963
6964 pos = 0;
6965 for (i=0; i<data_len; i++)
6966 pos += snprintf(str+pos, 200-pos, " %2.2x", data[i]);
6967
6968 ui_log("Unknown event from mc (%x %x)\n"
6969 "%4.4x:%2.2x %lld: %s\n",
6970 mcid.channel, mcid.mc_num, record_id, type, (int64_t) timestamp,
6971 str);
6972 }
6973
6974 static void
redisplay_timeout(void * cb_data,os_hnd_timer_id_t * id)6975 redisplay_timeout(void *cb_data, os_hnd_timer_id_t *id)
6976 {
6977 struct timeval now;
6978 int rv;
6979
6980 if (!full_screen)
6981 return;
6982
6983 if (curr_display_type == DISPLAY_ENTITIES) {
6984 rv = ipmi_domain_pointer_cb(domain_id, entities_cmder, &rv);
6985 if (rv)
6986 ui_log("redisplay_timeout:"
6987 " Unable to convert BMC id to a pointer\n");
6988 } else if (curr_display_type == DISPLAY_SENSOR) {
6989 rv = ipmi_sensor_pointer_cb(curr_sensor_id, redisplay_sensor, NULL);
6990 if (rv)
6991 ui_log("redisplay_timeout: Unable to get sensor pointer: 0x%x\n",
6992 rv);
6993 } else if (curr_display_type == DISPLAY_CONTROL) {
6994 rv = ipmi_control_pointer_cb(curr_control_id, redisplay_control, NULL);
6995 if (rv)
6996 ui_log("redisplay_timeout: Unable to get sensor pointer: 0x%x\n",
6997 rv);
6998 }
6999
7000 ipmi_ui_os_hnd->get_monotonic_time(ipmi_ui_os_hnd, &now);
7001 now.tv_sec += 1;
7002 rv = ipmi_ui_os_hnd->start_timer(ipmi_ui_os_hnd, id, &now,
7003 redisplay_timeout, NULL);
7004 if (rv)
7005 ui_log("Unable to restart redisplay timer: 0x%x\n", rv);
7006 }
7007
7008 void
ipmi_ui_setup_done(ipmi_domain_t * domain,int err,unsigned int conn_num,unsigned int port_num,int still_connected,void * cb_data)7009 ipmi_ui_setup_done(ipmi_domain_t *domain,
7010 int err,
7011 unsigned int conn_num,
7012 unsigned int port_num,
7013 int still_connected,
7014 void *cb_data)
7015 {
7016 int rv;
7017
7018 if (err)
7019 ui_log("IPMI connection to con.port %d.%d is down"
7020 " due to error 0x%x\n",
7021 conn_num, port_num, err);
7022 else
7023 ui_log("IPMI connection to con.port %d.%d is up\n",
7024 conn_num, port_num);
7025
7026 if (!still_connected) {
7027 ui_log("All IPMI connections down\n");
7028 return;
7029 }
7030
7031 domain_id = ipmi_domain_convert_to_id(domain);
7032
7033 rv = ipmi_domain_add_event_handler(domain, event_handler, NULL);
7034 if (rv)
7035 leave_err(rv, "ipmi_register_for_events");
7036
7037 rv = ipmi_domain_enable_events(domain);
7038 if (rv)
7039 leave_err(rv, "ipmi_domain_enable_events");
7040
7041 rv = ipmi_domain_add_entity_update_handler(domain, entity_change, domain);
7042 if (rv)
7043 leave_err(rv, "ipmi_bmc_set_entity_update_handler");
7044
7045 rv = ipmi_domain_add_mc_updated_handler(domain, mc_change, domain);
7046 if (rv)
7047 leave_err(rv, "ipmi_bmc_set_entity_update_handler");
7048 pef = NULL;
7049 lanparm = NULL;
7050 }
7051
7052 void
ipmi_ui_domain_ready(ipmi_domain_t * domain,int err,unsigned int conn_num,unsigned int port_num,int still_connected,void * user_data)7053 ipmi_ui_domain_ready(ipmi_domain_t *domain,
7054 int err,
7055 unsigned int conn_num,
7056 unsigned int port_num,
7057 int still_connected,
7058 void *user_data)
7059 {
7060 }
7061
7062 os_hnd_fd_id_t *user_input_id;
7063
7064 int
ipmi_ui_init(os_handler_t * os_hnd,int do_full_screen)7065 ipmi_ui_init(os_handler_t *os_hnd, int do_full_screen)
7066 {
7067 int rv;
7068
7069 full_screen = do_full_screen;
7070
7071 ipmi_ui_os_hnd = os_hnd;
7072
7073 ipmi_init(ipmi_ui_os_hnd);
7074
7075 rv = os_hnd->add_fd_to_wait_for(os_hnd, 0, user_input_ready, NULL, NULL,
7076 &user_input_id);
7077 if (rv) {
7078 fprintf(stderr, "Could not add stdin waiter: %s\n", strerror(rv));
7079 exit(1);
7080 }
7081
7082 /* This is a dummy allocation just to make sure that the malloc
7083 debugger is working. */
7084 ipmi_mem_alloc(10);
7085
7086 sensor_states = ipmi_mem_alloc(ipmi_states_size());
7087 if (!sensor_states) {
7088 fprintf(stderr, "Could not allocate sensor states\n");
7089 exit(1);
7090 }
7091
7092 sensor_event_states = ipmi_mem_alloc(ipmi_event_state_size());
7093 if (!sensor_event_states) {
7094 fprintf(stderr, "Could not allocate sensor event states\n");
7095 exit(1);
7096 }
7097
7098 sensor_thresholds = ipmi_mem_alloc(ipmi_thresholds_size());
7099 if (!sensor_thresholds) {
7100 fprintf(stderr, "Could not allocate sensor thresholds\n");
7101 exit(1);
7102 }
7103
7104 rv = init_commands();
7105 if (rv) {
7106 fprintf(stderr, "Could not initialize commands\n");
7107 exit(1);
7108 }
7109
7110 rv = init_keypad();
7111 if (rv) {
7112 fprintf(stderr, "Could not initialize keymap\n");
7113 exit(1);
7114 }
7115
7116 if (full_screen) {
7117 rv = init_win();
7118 if (rv) {
7119 fprintf(stderr, "Could not initialize curses\n");
7120 exit(1);
7121 }
7122 } else {
7123 struct termios new_termios;
7124
7125 tcgetattr(0, &old_termios);
7126 new_termios = old_termios;
7127 new_termios.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
7128 |INLCR|IGNCR|ICRNL|IXON);
7129 new_termios.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
7130 new_termios.c_cc[VTIME] = 0;
7131 new_termios.c_cc[VMIN] = 0;
7132 tcsetattr(0, TCSADRAIN, &new_termios);
7133 old_flags = fcntl(0, F_GETFL) & O_ACCMODE;
7134 // fcntl(0, F_SETFL, old_flags | O_NONBLOCK);
7135 }
7136
7137 help_cmd(NULL, NULL, NULL);
7138
7139 ui_log("Starting setup, wait until complete before entering commands.\n");
7140
7141 {
7142 struct timeval now;
7143
7144 rv = os_hnd->alloc_timer(os_hnd, &redisplay_timer);
7145 if (rv)
7146 leave_err(rv, "sel_alloc_timer");
7147 ipmi_ui_os_hnd->get_monotonic_time(ipmi_ui_os_hnd, &now);
7148 now.tv_sec += 1;
7149 rv = os_hnd->start_timer(os_hnd, redisplay_timer, &now,
7150 redisplay_timeout, NULL);
7151 if (rv)
7152 leave_err(rv, "Unable to restart redisplay timer");
7153 }
7154
7155 return 0;
7156 }
7157
7158 void
ipmi_ui_shutdown(void)7159 ipmi_ui_shutdown(void)
7160 {
7161 ipmi_mem_free(sensor_states);
7162 sensor_states = NULL;
7163 ipmi_mem_free(sensor_event_states);
7164 sensor_event_states = NULL;
7165 ipmi_mem_free(sensor_thresholds);
7166 sensor_thresholds = NULL;
7167 leave(0, "");
7168 }
7169