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