xref: /openbmc/ipmitool/lib/ipmi_event.c (revision c18ec02f)
1*c18ec02fSPetter Reinholdtsen /*
2*c18ec02fSPetter Reinholdtsen  * Copyright (c) 2003 Sun Microsystems, Inc.  All Rights Reserved.
3*c18ec02fSPetter Reinholdtsen  *
4*c18ec02fSPetter Reinholdtsen  * Redistribution and use in source and binary forms, with or without
5*c18ec02fSPetter Reinholdtsen  * modification, are permitted provided that the following conditions
6*c18ec02fSPetter Reinholdtsen  * are met:
7*c18ec02fSPetter Reinholdtsen  *
8*c18ec02fSPetter Reinholdtsen  * Redistribution of source code must retain the above copyright
9*c18ec02fSPetter Reinholdtsen  * notice, this list of conditions and the following disclaimer.
10*c18ec02fSPetter Reinholdtsen  *
11*c18ec02fSPetter Reinholdtsen  * Redistribution in binary form must reproduce the above copyright
12*c18ec02fSPetter Reinholdtsen  * notice, this list of conditions and the following disclaimer in the
13*c18ec02fSPetter Reinholdtsen  * documentation and/or other materials provided with the distribution.
14*c18ec02fSPetter Reinholdtsen  *
15*c18ec02fSPetter Reinholdtsen  * Neither the name of Sun Microsystems, Inc. or the names of
16*c18ec02fSPetter Reinholdtsen  * contributors may be used to endorse or promote products derived
17*c18ec02fSPetter Reinholdtsen  * from this software without specific prior written permission.
18*c18ec02fSPetter Reinholdtsen  *
19*c18ec02fSPetter Reinholdtsen  * This software is provided "AS IS," without a warranty of any kind.
20*c18ec02fSPetter Reinholdtsen  * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
21*c18ec02fSPetter Reinholdtsen  * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
22*c18ec02fSPetter Reinholdtsen  * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED.
23*c18ec02fSPetter Reinholdtsen  * SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE
24*c18ec02fSPetter Reinholdtsen  * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
25*c18ec02fSPetter Reinholdtsen  * OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.  IN NO EVENT WILL
26*c18ec02fSPetter Reinholdtsen  * SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA,
27*c18ec02fSPetter Reinholdtsen  * OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR
28*c18ec02fSPetter Reinholdtsen  * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF
29*c18ec02fSPetter Reinholdtsen  * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
30*c18ec02fSPetter Reinholdtsen  * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
31*c18ec02fSPetter Reinholdtsen  */
32*c18ec02fSPetter Reinholdtsen 
33*c18ec02fSPetter Reinholdtsen #include <stdlib.h>
34*c18ec02fSPetter Reinholdtsen #include <stdio.h>
35*c18ec02fSPetter Reinholdtsen #include <string.h>
36*c18ec02fSPetter Reinholdtsen #include <sys/types.h>
37*c18ec02fSPetter Reinholdtsen #include <sys/socket.h>
38*c18ec02fSPetter Reinholdtsen #include <netinet/in.h>
39*c18ec02fSPetter Reinholdtsen #include <arpa/inet.h>
40*c18ec02fSPetter Reinholdtsen #include <errno.h>
41*c18ec02fSPetter Reinholdtsen #include <unistd.h>
42*c18ec02fSPetter Reinholdtsen #include <signal.h>
43*c18ec02fSPetter Reinholdtsen #include <ctype.h>
44*c18ec02fSPetter Reinholdtsen 
45*c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi.h>
46*c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_intf.h>
47*c18ec02fSPetter Reinholdtsen #include <ipmitool/helper.h>
48*c18ec02fSPetter Reinholdtsen #include <ipmitool/log.h>
49*c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_sel.h>
50*c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_strings.h>
51*c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_channel.h>
52*c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_event.h>
53*c18ec02fSPetter Reinholdtsen #include <ipmitool/ipmi_sdr.h>
54*c18ec02fSPetter Reinholdtsen 
55*c18ec02fSPetter Reinholdtsen 
56*c18ec02fSPetter Reinholdtsen static void
ipmi_event_msg_print(struct ipmi_intf * intf,struct platform_event_msg * pmsg)57*c18ec02fSPetter Reinholdtsen ipmi_event_msg_print(struct ipmi_intf * intf, struct platform_event_msg * pmsg)
58*c18ec02fSPetter Reinholdtsen {
59*c18ec02fSPetter Reinholdtsen 	struct sel_event_record sel_event;
60*c18ec02fSPetter Reinholdtsen 
61*c18ec02fSPetter Reinholdtsen 	memset(&sel_event, 0, sizeof(struct sel_event_record));
62*c18ec02fSPetter Reinholdtsen 
63*c18ec02fSPetter Reinholdtsen 	sel_event.record_id = 0;
64*c18ec02fSPetter Reinholdtsen 	sel_event.sel_type.standard_type.gen_id = 2;
65*c18ec02fSPetter Reinholdtsen 
66*c18ec02fSPetter Reinholdtsen 	sel_event.sel_type.standard_type.evm_rev        = pmsg->evm_rev;
67*c18ec02fSPetter Reinholdtsen 	sel_event.sel_type.standard_type.sensor_type    = pmsg->sensor_type;
68*c18ec02fSPetter Reinholdtsen 	sel_event.sel_type.standard_type.sensor_num     = pmsg->sensor_num;
69*c18ec02fSPetter Reinholdtsen 	sel_event.sel_type.standard_type.event_type     = pmsg->event_type;
70*c18ec02fSPetter Reinholdtsen 	sel_event.sel_type.standard_type.event_dir      = pmsg->event_dir;
71*c18ec02fSPetter Reinholdtsen 	sel_event.sel_type.standard_type.event_data[0]  = pmsg->event_data[0];
72*c18ec02fSPetter Reinholdtsen 	sel_event.sel_type.standard_type.event_data[1]  = pmsg->event_data[1];
73*c18ec02fSPetter Reinholdtsen 	sel_event.sel_type.standard_type.event_data[2]  = pmsg->event_data[2];
74*c18ec02fSPetter Reinholdtsen 
75*c18ec02fSPetter Reinholdtsen 	if (verbose)
76*c18ec02fSPetter Reinholdtsen 		ipmi_sel_print_extended_entry_verbose(intf, &sel_event);
77*c18ec02fSPetter Reinholdtsen 	else
78*c18ec02fSPetter Reinholdtsen 		ipmi_sel_print_extended_entry(intf, &sel_event);
79*c18ec02fSPetter Reinholdtsen }
80*c18ec02fSPetter Reinholdtsen 
81*c18ec02fSPetter Reinholdtsen static int
ipmi_send_platform_event(struct ipmi_intf * intf,struct platform_event_msg * emsg)82*c18ec02fSPetter Reinholdtsen ipmi_send_platform_event(struct ipmi_intf * intf, struct platform_event_msg * emsg)
83*c18ec02fSPetter Reinholdtsen {
84*c18ec02fSPetter Reinholdtsen 	struct ipmi_rs * rsp;
85*c18ec02fSPetter Reinholdtsen 	struct ipmi_rq req;
86*c18ec02fSPetter Reinholdtsen 	uint8_t rqdata[8];
87*c18ec02fSPetter Reinholdtsen 	uint8_t chmed;
88*c18ec02fSPetter Reinholdtsen 
89*c18ec02fSPetter Reinholdtsen 	memset(&req, 0, sizeof(req));
90*c18ec02fSPetter Reinholdtsen 	memset(rqdata, 0, 8);
91*c18ec02fSPetter Reinholdtsen 
92*c18ec02fSPetter Reinholdtsen 	req.msg.netfn = IPMI_NETFN_SE;
93*c18ec02fSPetter Reinholdtsen 	req.msg.cmd = 0x02;
94*c18ec02fSPetter Reinholdtsen 	req.msg.data = rqdata;
95*c18ec02fSPetter Reinholdtsen 
96*c18ec02fSPetter Reinholdtsen 	chmed = ipmi_current_channel_medium(intf);
97*c18ec02fSPetter Reinholdtsen 	if (chmed == IPMI_CHANNEL_MEDIUM_SYSTEM) {
98*c18ec02fSPetter Reinholdtsen 		/* system interface, need extra generator ID */
99*c18ec02fSPetter Reinholdtsen 		req.msg.data_len = 8;
100*c18ec02fSPetter Reinholdtsen 		rqdata[0] = 0x41;   // As per Fig. 29-2 and Table 5-4
101*c18ec02fSPetter Reinholdtsen 		memcpy(rqdata+1, emsg, sizeof(struct platform_event_msg));
102*c18ec02fSPetter Reinholdtsen 	}
103*c18ec02fSPetter Reinholdtsen 	else {
104*c18ec02fSPetter Reinholdtsen 		req.msg.data_len = 7;
105*c18ec02fSPetter Reinholdtsen 		memcpy(rqdata, emsg, sizeof(struct platform_event_msg));
106*c18ec02fSPetter Reinholdtsen 	}
107*c18ec02fSPetter Reinholdtsen 
108*c18ec02fSPetter Reinholdtsen 	ipmi_event_msg_print(intf, emsg);
109*c18ec02fSPetter Reinholdtsen 
110*c18ec02fSPetter Reinholdtsen 	rsp = intf->sendrecv(intf, &req);
111*c18ec02fSPetter Reinholdtsen 	if (rsp == NULL) {
112*c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Platform Event Message command failed");
113*c18ec02fSPetter Reinholdtsen 		return -1;
114*c18ec02fSPetter Reinholdtsen 	}
115*c18ec02fSPetter Reinholdtsen 	else if (rsp->ccode > 0) {
116*c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Platform Event Message command failed: %s",
117*c18ec02fSPetter Reinholdtsen 			val2str(rsp->ccode, completion_code_vals));
118*c18ec02fSPetter Reinholdtsen 		return -1;
119*c18ec02fSPetter Reinholdtsen 	}
120*c18ec02fSPetter Reinholdtsen 
121*c18ec02fSPetter Reinholdtsen 	return 0;
122*c18ec02fSPetter Reinholdtsen }
123*c18ec02fSPetter Reinholdtsen 
124*c18ec02fSPetter Reinholdtsen #define EVENT_THRESH_STATE_LNC_LO	0
125*c18ec02fSPetter Reinholdtsen #define EVENT_THRESH_STATE_LNC_HI	1
126*c18ec02fSPetter Reinholdtsen #define EVENT_THRESH_STATE_LCR_LO	2
127*c18ec02fSPetter Reinholdtsen #define EVENT_THRESH_STATE_LCR_HI	3
128*c18ec02fSPetter Reinholdtsen #define EVENT_THRESH_STATE_LNR_LO	4
129*c18ec02fSPetter Reinholdtsen #define EVENT_THRESH_STATE_LNR_HI	5
130*c18ec02fSPetter Reinholdtsen #define EVENT_THRESH_STATE_UNC_LO	6
131*c18ec02fSPetter Reinholdtsen #define EVENT_THRESH_STATE_UNC_HI	7
132*c18ec02fSPetter Reinholdtsen #define EVENT_THRESH_STATE_UCR_LO	8
133*c18ec02fSPetter Reinholdtsen #define EVENT_THRESH_STATE_UCR_HI	9
134*c18ec02fSPetter Reinholdtsen #define EVENT_THRESH_STATE_UNR_LO	10
135*c18ec02fSPetter Reinholdtsen #define EVENT_THRESH_STATE_UNR_HI	11
136*c18ec02fSPetter Reinholdtsen 
137*c18ec02fSPetter Reinholdtsen static const struct valstr ipmi_event_thresh_lo[] = {
138*c18ec02fSPetter Reinholdtsen 	{ EVENT_THRESH_STATE_LNC_LO, "lnc" },
139*c18ec02fSPetter Reinholdtsen 	{ EVENT_THRESH_STATE_LCR_LO, "lcr" },
140*c18ec02fSPetter Reinholdtsen 	{ EVENT_THRESH_STATE_LNR_LO, "lnr" },
141*c18ec02fSPetter Reinholdtsen 	{ EVENT_THRESH_STATE_UNC_LO, "unc" },
142*c18ec02fSPetter Reinholdtsen 	{ EVENT_THRESH_STATE_UCR_LO, "ucr" },
143*c18ec02fSPetter Reinholdtsen 	{ EVENT_THRESH_STATE_UNR_LO, "unr" },
144*c18ec02fSPetter Reinholdtsen 	{ 0, NULL  },
145*c18ec02fSPetter Reinholdtsen };
146*c18ec02fSPetter Reinholdtsen static const struct valstr ipmi_event_thresh_hi[] = {
147*c18ec02fSPetter Reinholdtsen 	{ EVENT_THRESH_STATE_LNC_HI, "lnc" },
148*c18ec02fSPetter Reinholdtsen 	{ EVENT_THRESH_STATE_LCR_HI, "lcr" },
149*c18ec02fSPetter Reinholdtsen 	{ EVENT_THRESH_STATE_LNR_HI, "lnr" },
150*c18ec02fSPetter Reinholdtsen 	{ EVENT_THRESH_STATE_UNC_HI, "unc" },
151*c18ec02fSPetter Reinholdtsen 	{ EVENT_THRESH_STATE_UCR_HI, "ucr" },
152*c18ec02fSPetter Reinholdtsen 	{ EVENT_THRESH_STATE_UNR_HI, "unr" },
153*c18ec02fSPetter Reinholdtsen 	{ 0, NULL  },
154*c18ec02fSPetter Reinholdtsen };
155*c18ec02fSPetter Reinholdtsen 
156*c18ec02fSPetter Reinholdtsen static int
ipmi_send_platform_event_num(struct ipmi_intf * intf,int num)157*c18ec02fSPetter Reinholdtsen ipmi_send_platform_event_num(struct ipmi_intf * intf, int num)
158*c18ec02fSPetter Reinholdtsen {
159*c18ec02fSPetter Reinholdtsen 	struct platform_event_msg emsg;
160*c18ec02fSPetter Reinholdtsen 
161*c18ec02fSPetter Reinholdtsen 	memset(&emsg, 0, sizeof(struct platform_event_msg));
162*c18ec02fSPetter Reinholdtsen 
163*c18ec02fSPetter Reinholdtsen 	/* IPMB/LAN/etc */
164*c18ec02fSPetter Reinholdtsen 	switch (num) {
165*c18ec02fSPetter Reinholdtsen 	case 1:			/* temperature */
166*c18ec02fSPetter Reinholdtsen 		printf("Sending SAMPLE event: Temperature - "
167*c18ec02fSPetter Reinholdtsen 		       "Upper Critical - Going High\n");
168*c18ec02fSPetter Reinholdtsen 		emsg.evm_rev       = 0x04;
169*c18ec02fSPetter Reinholdtsen 		emsg.sensor_type   = 0x01;
170*c18ec02fSPetter Reinholdtsen 		emsg.sensor_num    = 0x30;
171*c18ec02fSPetter Reinholdtsen 		emsg.event_dir     = EVENT_DIR_ASSERT;
172*c18ec02fSPetter Reinholdtsen 		emsg.event_type    = 0x01;
173*c18ec02fSPetter Reinholdtsen 		emsg.event_data[0] = EVENT_THRESH_STATE_UCR_HI;
174*c18ec02fSPetter Reinholdtsen 		emsg.event_data[1] = 0xff;
175*c18ec02fSPetter Reinholdtsen 		emsg.event_data[2] = 0xff;
176*c18ec02fSPetter Reinholdtsen 		break;
177*c18ec02fSPetter Reinholdtsen 	case 2:			/* voltage error */
178*c18ec02fSPetter Reinholdtsen 		printf("Sending SAMPLE event: Voltage Threshold - "
179*c18ec02fSPetter Reinholdtsen 		       "Lower Critical - Going Low\n");
180*c18ec02fSPetter Reinholdtsen 		emsg.evm_rev       = 0x04;
181*c18ec02fSPetter Reinholdtsen 		emsg.sensor_type   = 0x02;
182*c18ec02fSPetter Reinholdtsen 		emsg.sensor_num    = 0x60;
183*c18ec02fSPetter Reinholdtsen 		emsg.event_dir     = EVENT_DIR_ASSERT;
184*c18ec02fSPetter Reinholdtsen 		emsg.event_type    = 0x01;
185*c18ec02fSPetter Reinholdtsen 		emsg.event_data[0] = EVENT_THRESH_STATE_LCR_LO;
186*c18ec02fSPetter Reinholdtsen 		emsg.event_data[1] = 0xff;
187*c18ec02fSPetter Reinholdtsen 		emsg.event_data[2] = 0xff;
188*c18ec02fSPetter Reinholdtsen 		break;
189*c18ec02fSPetter Reinholdtsen 	case 3:			/* correctable ECC */
190*c18ec02fSPetter Reinholdtsen 		printf("Sending SAMPLE event: Memory - Correctable ECC\n");
191*c18ec02fSPetter Reinholdtsen 		emsg.evm_rev       = 0x04;
192*c18ec02fSPetter Reinholdtsen 		emsg.sensor_type   = 0x0c;
193*c18ec02fSPetter Reinholdtsen 		emsg.sensor_num    = 0x53;
194*c18ec02fSPetter Reinholdtsen 		emsg.event_dir     = EVENT_DIR_ASSERT;
195*c18ec02fSPetter Reinholdtsen 		emsg.event_type    = 0x6f;
196*c18ec02fSPetter Reinholdtsen 		emsg.event_data[0] = 0x00;
197*c18ec02fSPetter Reinholdtsen 		emsg.event_data[1] = 0xff;
198*c18ec02fSPetter Reinholdtsen 		emsg.event_data[2] = 0xff;
199*c18ec02fSPetter Reinholdtsen 		break;
200*c18ec02fSPetter Reinholdtsen 	default:
201*c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Invalid event number: %d", num);
202*c18ec02fSPetter Reinholdtsen 		return -1;
203*c18ec02fSPetter Reinholdtsen 	}
204*c18ec02fSPetter Reinholdtsen 
205*c18ec02fSPetter Reinholdtsen 	return ipmi_send_platform_event(intf, &emsg);
206*c18ec02fSPetter Reinholdtsen }
207*c18ec02fSPetter Reinholdtsen 
208*c18ec02fSPetter Reinholdtsen static int
ipmi_event_find_offset(uint8_t code,struct ipmi_event_sensor_types * evt,char * desc)209*c18ec02fSPetter Reinholdtsen ipmi_event_find_offset(uint8_t code,
210*c18ec02fSPetter Reinholdtsen 		       struct ipmi_event_sensor_types * evt,
211*c18ec02fSPetter Reinholdtsen 		       char * desc)
212*c18ec02fSPetter Reinholdtsen {
213*c18ec02fSPetter Reinholdtsen 	if (desc == NULL || code == 0)
214*c18ec02fSPetter Reinholdtsen 		return 0x00;
215*c18ec02fSPetter Reinholdtsen 
216*c18ec02fSPetter Reinholdtsen 	while (evt->type) {
217*c18ec02fSPetter Reinholdtsen 		if (evt->code == code && evt->desc != NULL &&
218*c18ec02fSPetter Reinholdtsen 		    strncasecmp(desc, evt->desc, __maxlen(desc, evt->desc)) == 0)
219*c18ec02fSPetter Reinholdtsen 			return evt->offset;
220*c18ec02fSPetter Reinholdtsen 		evt++;
221*c18ec02fSPetter Reinholdtsen 	}
222*c18ec02fSPetter Reinholdtsen 
223*c18ec02fSPetter Reinholdtsen 	lprintf(LOG_WARN, "Unable to find matching event offset for '%s'", desc);
224*c18ec02fSPetter Reinholdtsen 	return -1;
225*c18ec02fSPetter Reinholdtsen }
226*c18ec02fSPetter Reinholdtsen 
227*c18ec02fSPetter Reinholdtsen static void
print_sensor_states(uint8_t sensor_type,uint8_t event_type)228*c18ec02fSPetter Reinholdtsen print_sensor_states(uint8_t sensor_type, uint8_t event_type)
229*c18ec02fSPetter Reinholdtsen {
230*c18ec02fSPetter Reinholdtsen 	ipmi_sdr_print_discrete_state_mini(
231*c18ec02fSPetter Reinholdtsen 			"Sensor States: \n  ", "\n  ", sensor_type,
232*c18ec02fSPetter Reinholdtsen 					   event_type, 0xff, 0xff);
233*c18ec02fSPetter Reinholdtsen 	printf("\n");
234*c18ec02fSPetter Reinholdtsen }
235*c18ec02fSPetter Reinholdtsen 
236*c18ec02fSPetter Reinholdtsen 
237*c18ec02fSPetter Reinholdtsen static int
ipmi_event_fromsensor(struct ipmi_intf * intf,char * id,char * state,char * evdir)238*c18ec02fSPetter Reinholdtsen ipmi_event_fromsensor(struct ipmi_intf * intf, char * id, char * state, char * evdir)
239*c18ec02fSPetter Reinholdtsen {
240*c18ec02fSPetter Reinholdtsen 	struct ipmi_rs * rsp;
241*c18ec02fSPetter Reinholdtsen 	struct sdr_record_list * sdr;
242*c18ec02fSPetter Reinholdtsen 	struct platform_event_msg emsg;
243*c18ec02fSPetter Reinholdtsen 	int off;
244*c18ec02fSPetter Reinholdtsen 	uint8_t target, lun, channel;
245*c18ec02fSPetter Reinholdtsen 
246*c18ec02fSPetter Reinholdtsen 	if (id == NULL) {
247*c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "No sensor ID supplied");
248*c18ec02fSPetter Reinholdtsen 		return -1;
249*c18ec02fSPetter Reinholdtsen 	}
250*c18ec02fSPetter Reinholdtsen 
251*c18ec02fSPetter Reinholdtsen 	memset(&emsg, 0, sizeof(struct platform_event_msg));
252*c18ec02fSPetter Reinholdtsen 	emsg.evm_rev = 0x04;
253*c18ec02fSPetter Reinholdtsen 
254*c18ec02fSPetter Reinholdtsen 	if (evdir == NULL)
255*c18ec02fSPetter Reinholdtsen 		emsg.event_dir = EVENT_DIR_ASSERT;
256*c18ec02fSPetter Reinholdtsen 	else if (strncasecmp(evdir, "assert", 6) == 0)
257*c18ec02fSPetter Reinholdtsen 		emsg.event_dir = EVENT_DIR_ASSERT;
258*c18ec02fSPetter Reinholdtsen 	else if (strncasecmp(evdir, "deassert", 8) == 0)
259*c18ec02fSPetter Reinholdtsen 		emsg.event_dir = EVENT_DIR_DEASSERT;
260*c18ec02fSPetter Reinholdtsen 	else {
261*c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Invalid event direction %s.  Must be 'assert' or 'deassert'", evdir);
262*c18ec02fSPetter Reinholdtsen 		return -1;
263*c18ec02fSPetter Reinholdtsen 	}
264*c18ec02fSPetter Reinholdtsen 
265*c18ec02fSPetter Reinholdtsen 	printf("Finding sensor %s... ", id);
266*c18ec02fSPetter Reinholdtsen 	sdr = ipmi_sdr_find_sdr_byid(intf, id);
267*c18ec02fSPetter Reinholdtsen 	if (sdr == NULL) {
268*c18ec02fSPetter Reinholdtsen 		printf("not found!\n");
269*c18ec02fSPetter Reinholdtsen 		return -1;
270*c18ec02fSPetter Reinholdtsen 	}
271*c18ec02fSPetter Reinholdtsen 	printf("ok\n");
272*c18ec02fSPetter Reinholdtsen 
273*c18ec02fSPetter Reinholdtsen 	switch (sdr->type)
274*c18ec02fSPetter Reinholdtsen 	{
275*c18ec02fSPetter Reinholdtsen 	case SDR_RECORD_TYPE_FULL_SENSOR:
276*c18ec02fSPetter Reinholdtsen 	case SDR_RECORD_TYPE_COMPACT_SENSOR:
277*c18ec02fSPetter Reinholdtsen 
278*c18ec02fSPetter Reinholdtsen 		emsg.sensor_type   = sdr->record.common->sensor.type;
279*c18ec02fSPetter Reinholdtsen 		emsg.sensor_num    = sdr->record.common->keys.sensor_num;
280*c18ec02fSPetter Reinholdtsen 		emsg.event_type    = sdr->record.common->event_type;
281*c18ec02fSPetter Reinholdtsen 		target    = sdr->record.common->keys.owner_id;
282*c18ec02fSPetter Reinholdtsen 		lun    = sdr->record.common->keys.lun;
283*c18ec02fSPetter Reinholdtsen 		channel = sdr->record.common->keys.channel;
284*c18ec02fSPetter Reinholdtsen 		break;
285*c18ec02fSPetter Reinholdtsen 	default:
286*c18ec02fSPetter Reinholdtsen 		lprintf(LOG_ERR, "Unknown sensor type for id '%s'", id);
287*c18ec02fSPetter Reinholdtsen 		return -1;
288*c18ec02fSPetter Reinholdtsen 	}
289*c18ec02fSPetter Reinholdtsen 
290*c18ec02fSPetter Reinholdtsen 	emsg.event_data[1] = 0xff;
291*c18ec02fSPetter Reinholdtsen 	emsg.event_data[2] = 0xff;
292*c18ec02fSPetter Reinholdtsen 
293*c18ec02fSPetter Reinholdtsen 	switch (emsg.event_type)
294*c18ec02fSPetter Reinholdtsen 	{
295*c18ec02fSPetter Reinholdtsen 	/*
296*c18ec02fSPetter Reinholdtsen 	 * Threshold Class
297*c18ec02fSPetter Reinholdtsen 	 */
298*c18ec02fSPetter Reinholdtsen 	case 1:
299*c18ec02fSPetter Reinholdtsen 	{
300*c18ec02fSPetter Reinholdtsen 		int dir = 0;
301*c18ec02fSPetter Reinholdtsen 		int hilo = 0;
302*c18ec02fSPetter Reinholdtsen 		off = 1;
303*c18ec02fSPetter Reinholdtsen 
304*c18ec02fSPetter Reinholdtsen 		if (state == NULL || strncasecmp(state, "list", 4) == 0) {
305*c18ec02fSPetter Reinholdtsen 			printf("Sensor States:\n");
306*c18ec02fSPetter Reinholdtsen 			printf("  lnr : Lower Non-Recoverable \n");
307*c18ec02fSPetter Reinholdtsen 			printf("  lcr : Lower Critical\n");
308*c18ec02fSPetter Reinholdtsen 			printf("  lnc : Lower Non-Critical\n");
309*c18ec02fSPetter Reinholdtsen 			printf("  unc : Upper Non-Critical\n");
310*c18ec02fSPetter Reinholdtsen 			printf("  ucr : Upper Critical\n");
311*c18ec02fSPetter Reinholdtsen 			printf("  unr : Upper Non-Recoverable\n");
312*c18ec02fSPetter Reinholdtsen 			return -1;
313*c18ec02fSPetter Reinholdtsen 		}
314*c18ec02fSPetter Reinholdtsen 
315*c18ec02fSPetter Reinholdtsen 		if (0 != strncasecmp(state, "lnr", 3) &&
316*c18ec02fSPetter Reinholdtsen 		    0 != strncasecmp(state, "lcr", 3) &&
317*c18ec02fSPetter Reinholdtsen 		    0 != strncasecmp(state, "lnc", 3) &&
318*c18ec02fSPetter Reinholdtsen 		    0 != strncasecmp(state, "unc", 3) &&
319*c18ec02fSPetter Reinholdtsen 		    0 != strncasecmp(state, "ucr", 3) &&
320*c18ec02fSPetter Reinholdtsen 		    0 != strncasecmp(state, "unr", 3))
321*c18ec02fSPetter Reinholdtsen 		{
322*c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "Invalid threshold identifier %s", state);
323*c18ec02fSPetter Reinholdtsen 			return -1;
324*c18ec02fSPetter Reinholdtsen 		}
325*c18ec02fSPetter Reinholdtsen 
326*c18ec02fSPetter Reinholdtsen 		if (state[0] == 'u')
327*c18ec02fSPetter Reinholdtsen 			hilo = 1;
328*c18ec02fSPetter Reinholdtsen 		else
329*c18ec02fSPetter Reinholdtsen 			hilo = 0;
330*c18ec02fSPetter Reinholdtsen 
331*c18ec02fSPetter Reinholdtsen 		if (emsg.event_dir == EVENT_DIR_ASSERT)
332*c18ec02fSPetter Reinholdtsen 			dir = hilo;
333*c18ec02fSPetter Reinholdtsen 		else
334*c18ec02fSPetter Reinholdtsen 			dir = !hilo;
335*c18ec02fSPetter Reinholdtsen 
336*c18ec02fSPetter Reinholdtsen 		if ((emsg.event_dir == EVENT_DIR_ASSERT   && hilo == 1) ||
337*c18ec02fSPetter Reinholdtsen 		    (emsg.event_dir == EVENT_DIR_DEASSERT && hilo == 0))
338*c18ec02fSPetter Reinholdtsen 			emsg.event_data[0] = (uint8_t)(str2val(state, ipmi_event_thresh_hi) & 0xf);
339*c18ec02fSPetter Reinholdtsen 		else if ((emsg.event_dir == EVENT_DIR_ASSERT   && hilo == 0) ||
340*c18ec02fSPetter Reinholdtsen 			 (emsg.event_dir == EVENT_DIR_DEASSERT && hilo == 1))
341*c18ec02fSPetter Reinholdtsen 			emsg.event_data[0] = (uint8_t)(str2val(state, ipmi_event_thresh_lo) & 0xf);
342*c18ec02fSPetter Reinholdtsen 		else {
343*c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "Invalid Event");
344*c18ec02fSPetter Reinholdtsen 			return -1;
345*c18ec02fSPetter Reinholdtsen 		}
346*c18ec02fSPetter Reinholdtsen 
347*c18ec02fSPetter Reinholdtsen 		rsp = ipmi_sdr_get_sensor_thresholds(intf, emsg.sensor_num,
348*c18ec02fSPetter Reinholdtsen 							target, lun, channel);
349*c18ec02fSPetter Reinholdtsen 		if (rsp == NULL) {
350*c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR,
351*c18ec02fSPetter Reinholdtsen 					"Command Get Sensor Thresholds failed: invalid response.");
352*c18ec02fSPetter Reinholdtsen 			return (-1);
353*c18ec02fSPetter Reinholdtsen 		} else if (rsp->ccode != 0) {
354*c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "Command Get Sensor Thresholds failed: %s",
355*c18ec02fSPetter Reinholdtsen 					val2str(rsp->ccode, completion_code_vals));
356*c18ec02fSPetter Reinholdtsen 			return (-1);
357*c18ec02fSPetter Reinholdtsen 		}
358*c18ec02fSPetter Reinholdtsen 
359*c18ec02fSPetter Reinholdtsen 		/* threshold reading */
360*c18ec02fSPetter Reinholdtsen 		emsg.event_data[2] = rsp->data[(emsg.event_data[0] / 2) + 1];
361*c18ec02fSPetter Reinholdtsen 
362*c18ec02fSPetter Reinholdtsen 		rsp = ipmi_sdr_get_sensor_hysteresis(intf, emsg.sensor_num,
363*c18ec02fSPetter Reinholdtsen 							target, lun, channel);
364*c18ec02fSPetter Reinholdtsen 		if (rsp != NULL && rsp->ccode == 0)
365*c18ec02fSPetter Reinholdtsen 			off = dir ? rsp->data[0] : rsp->data[1];
366*c18ec02fSPetter Reinholdtsen 		if (off <= 0)
367*c18ec02fSPetter Reinholdtsen 			off = 1;
368*c18ec02fSPetter Reinholdtsen 
369*c18ec02fSPetter Reinholdtsen 		/* trigger reading */
370*c18ec02fSPetter Reinholdtsen 		if (dir) {
371*c18ec02fSPetter Reinholdtsen 			if ((emsg.event_data[2] + off) > 0xff)
372*c18ec02fSPetter Reinholdtsen 				emsg.event_data[1] = 0xff;
373*c18ec02fSPetter Reinholdtsen 			else
374*c18ec02fSPetter Reinholdtsen 				emsg.event_data[1] = emsg.event_data[2] + off;
375*c18ec02fSPetter Reinholdtsen 		}
376*c18ec02fSPetter Reinholdtsen 		else {
377*c18ec02fSPetter Reinholdtsen 			if ((emsg.event_data[2] - off) < 0)
378*c18ec02fSPetter Reinholdtsen 				emsg.event_data[1] = 0;
379*c18ec02fSPetter Reinholdtsen 			else
380*c18ec02fSPetter Reinholdtsen 				emsg.event_data[1] = emsg.event_data[2] - off;
381*c18ec02fSPetter Reinholdtsen 		}
382*c18ec02fSPetter Reinholdtsen 
383*c18ec02fSPetter Reinholdtsen 		/* trigger in byte 2, threshold in byte 3 */
384*c18ec02fSPetter Reinholdtsen 		emsg.event_data[0] |= 0x50;
385*c18ec02fSPetter Reinholdtsen 	}
386*c18ec02fSPetter Reinholdtsen 	break;
387*c18ec02fSPetter Reinholdtsen 
388*c18ec02fSPetter Reinholdtsen 	/*
389*c18ec02fSPetter Reinholdtsen 	 * Digital Discrete
390*c18ec02fSPetter Reinholdtsen 	 */
391*c18ec02fSPetter Reinholdtsen 	case 3: case 4: case 5: case 6: case 8: case 9:
392*c18ec02fSPetter Reinholdtsen 	{
393*c18ec02fSPetter Reinholdtsen 		int x;
394*c18ec02fSPetter Reinholdtsen 		const char * digi_on[] = { "present", "assert", "limit",
395*c18ec02fSPetter Reinholdtsen 					   "fail", "yes", "on", "up" };
396*c18ec02fSPetter Reinholdtsen 		const char * digi_off[] = { "absent", "deassert", "nolimit",
397*c18ec02fSPetter Reinholdtsen 					    "nofail", "no", "off", "down" };
398*c18ec02fSPetter Reinholdtsen 		/*
399*c18ec02fSPetter Reinholdtsen 		 * print list of available states for this sensor
400*c18ec02fSPetter Reinholdtsen 		 */
401*c18ec02fSPetter Reinholdtsen 		if (state == NULL || strncasecmp(state, "list", 4) == 0) {
402*c18ec02fSPetter Reinholdtsen 			print_sensor_states(emsg.sensor_type, emsg.event_type);
403*c18ec02fSPetter Reinholdtsen 			printf("Sensor State Shortcuts:\n");
404*c18ec02fSPetter Reinholdtsen 			for (x = 0; x < sizeof(digi_on)/sizeof(*digi_on); x++) {
405*c18ec02fSPetter Reinholdtsen 				printf("  %-9s  %-9s\n", digi_on[x], digi_off[x]);
406*c18ec02fSPetter Reinholdtsen 			}
407*c18ec02fSPetter Reinholdtsen 			return 0;
408*c18ec02fSPetter Reinholdtsen 		}
409*c18ec02fSPetter Reinholdtsen 
410*c18ec02fSPetter Reinholdtsen 		off = 0;
411*c18ec02fSPetter Reinholdtsen 		for (x = 0; x < sizeof(digi_on)/sizeof(*digi_on); x++) {
412*c18ec02fSPetter Reinholdtsen 			if (strncasecmp(state, digi_on[x], strlen(digi_on[x])) == 0) {
413*c18ec02fSPetter Reinholdtsen 				emsg.event_data[0] = 1;
414*c18ec02fSPetter Reinholdtsen 				off = 1;
415*c18ec02fSPetter Reinholdtsen 				break;
416*c18ec02fSPetter Reinholdtsen 			}
417*c18ec02fSPetter Reinholdtsen 			else if (strncasecmp(state, digi_off[x], strlen(digi_off[x])) == 0) {
418*c18ec02fSPetter Reinholdtsen 				emsg.event_data[0] = 0;
419*c18ec02fSPetter Reinholdtsen 				off = 1;
420*c18ec02fSPetter Reinholdtsen 				break;
421*c18ec02fSPetter Reinholdtsen 			}
422*c18ec02fSPetter Reinholdtsen 		}
423*c18ec02fSPetter Reinholdtsen 		if (off == 0) {
424*c18ec02fSPetter Reinholdtsen 			off = ipmi_event_find_offset(
425*c18ec02fSPetter Reinholdtsen 				emsg.event_type, generic_event_types, state);
426*c18ec02fSPetter Reinholdtsen 			if (off < 0)
427*c18ec02fSPetter Reinholdtsen 				return -1;
428*c18ec02fSPetter Reinholdtsen 			emsg.event_data[0] = off;
429*c18ec02fSPetter Reinholdtsen 		}
430*c18ec02fSPetter Reinholdtsen 	}
431*c18ec02fSPetter Reinholdtsen 	break;
432*c18ec02fSPetter Reinholdtsen 
433*c18ec02fSPetter Reinholdtsen 	/*
434*c18ec02fSPetter Reinholdtsen 	 * Generic Discrete
435*c18ec02fSPetter Reinholdtsen 	 */
436*c18ec02fSPetter Reinholdtsen 	case 2: case 7: case 10: case 11: case 12:
437*c18ec02fSPetter Reinholdtsen 	{
438*c18ec02fSPetter Reinholdtsen 		/*
439*c18ec02fSPetter Reinholdtsen 		 * print list of available states for this sensor
440*c18ec02fSPetter Reinholdtsen 		 */
441*c18ec02fSPetter Reinholdtsen 		if (state == NULL || strncasecmp(state, "list", 4) == 0) {
442*c18ec02fSPetter Reinholdtsen 			print_sensor_states(emsg.sensor_type, emsg.event_type);
443*c18ec02fSPetter Reinholdtsen 			return 0;
444*c18ec02fSPetter Reinholdtsen 		}
445*c18ec02fSPetter Reinholdtsen 		off = ipmi_event_find_offset(
446*c18ec02fSPetter Reinholdtsen 			emsg.event_type, generic_event_types, state);
447*c18ec02fSPetter Reinholdtsen 		if (off < 0)
448*c18ec02fSPetter Reinholdtsen 			return -1;
449*c18ec02fSPetter Reinholdtsen 		emsg.event_data[0] = off;
450*c18ec02fSPetter Reinholdtsen 	}
451*c18ec02fSPetter Reinholdtsen 	break;
452*c18ec02fSPetter Reinholdtsen 
453*c18ec02fSPetter Reinholdtsen 	/*
454*c18ec02fSPetter Reinholdtsen 	 * Sensor-Specific Discrete
455*c18ec02fSPetter Reinholdtsen 	 */
456*c18ec02fSPetter Reinholdtsen 	case 0x6f:
457*c18ec02fSPetter Reinholdtsen 	{
458*c18ec02fSPetter Reinholdtsen 		/*
459*c18ec02fSPetter Reinholdtsen 		 * print list of available states for this sensor
460*c18ec02fSPetter Reinholdtsen 		 */
461*c18ec02fSPetter Reinholdtsen 		if (state == NULL || strncasecmp(state, "list", 4) == 0) {
462*c18ec02fSPetter Reinholdtsen 			print_sensor_states(emsg.sensor_type, emsg.event_type);
463*c18ec02fSPetter Reinholdtsen 			return 0;
464*c18ec02fSPetter Reinholdtsen 		}
465*c18ec02fSPetter Reinholdtsen 		off = ipmi_event_find_offset(
466*c18ec02fSPetter Reinholdtsen 			emsg.sensor_type, sensor_specific_types, state);
467*c18ec02fSPetter Reinholdtsen 		if (off < 0)
468*c18ec02fSPetter Reinholdtsen 			return -1;
469*c18ec02fSPetter Reinholdtsen 		emsg.event_data[0] = off;
470*c18ec02fSPetter Reinholdtsen 	}
471*c18ec02fSPetter Reinholdtsen 	break;
472*c18ec02fSPetter Reinholdtsen 
473*c18ec02fSPetter Reinholdtsen 	default:
474*c18ec02fSPetter Reinholdtsen 		return -1;
475*c18ec02fSPetter Reinholdtsen 
476*c18ec02fSPetter Reinholdtsen 	}
477*c18ec02fSPetter Reinholdtsen 
478*c18ec02fSPetter Reinholdtsen 	return ipmi_send_platform_event(intf, &emsg);
479*c18ec02fSPetter Reinholdtsen }
480*c18ec02fSPetter Reinholdtsen 
481*c18ec02fSPetter Reinholdtsen static int
ipmi_event_fromfile(struct ipmi_intf * intf,char * file)482*c18ec02fSPetter Reinholdtsen ipmi_event_fromfile(struct ipmi_intf * intf, char * file)
483*c18ec02fSPetter Reinholdtsen {
484*c18ec02fSPetter Reinholdtsen 	FILE * fp;
485*c18ec02fSPetter Reinholdtsen 	struct ipmi_rs * rsp;
486*c18ec02fSPetter Reinholdtsen 	struct ipmi_rq req;
487*c18ec02fSPetter Reinholdtsen 	struct sel_event_record sel_event;
488*c18ec02fSPetter Reinholdtsen 	uint8_t rqdata[8];
489*c18ec02fSPetter Reinholdtsen 	char buf[1024];
490*c18ec02fSPetter Reinholdtsen 	char * ptr, * tok;
491*c18ec02fSPetter Reinholdtsen 	int i, j;
492*c18ec02fSPetter Reinholdtsen 	uint8_t chmed;
493*c18ec02fSPetter Reinholdtsen 	int rc = 0;
494*c18ec02fSPetter Reinholdtsen 
495*c18ec02fSPetter Reinholdtsen 	if (file == NULL)
496*c18ec02fSPetter Reinholdtsen 		return -1;
497*c18ec02fSPetter Reinholdtsen 
498*c18ec02fSPetter Reinholdtsen 	memset(rqdata, 0, 8);
499*c18ec02fSPetter Reinholdtsen 
500*c18ec02fSPetter Reinholdtsen 	/* setup Platform Event Message command */
501*c18ec02fSPetter Reinholdtsen 	memset(&req, 0, sizeof(req));
502*c18ec02fSPetter Reinholdtsen 	req.msg.netfn = IPMI_NETFN_SE;
503*c18ec02fSPetter Reinholdtsen 	req.msg.cmd = 0x02;
504*c18ec02fSPetter Reinholdtsen 	req.msg.data = rqdata;
505*c18ec02fSPetter Reinholdtsen 	req.msg.data_len = 7;
506*c18ec02fSPetter Reinholdtsen 
507*c18ec02fSPetter Reinholdtsen 	chmed = ipmi_current_channel_medium(intf);
508*c18ec02fSPetter Reinholdtsen 	if (chmed == IPMI_CHANNEL_MEDIUM_SYSTEM) {
509*c18ec02fSPetter Reinholdtsen 		/* system interface, need extra generator ID */
510*c18ec02fSPetter Reinholdtsen 		rqdata[0] = 0x41;   // As per Fig. 29-2 and Table 5-4
511*c18ec02fSPetter Reinholdtsen 		req.msg.data_len = 8;
512*c18ec02fSPetter Reinholdtsen 	}
513*c18ec02fSPetter Reinholdtsen 
514*c18ec02fSPetter Reinholdtsen 	fp = ipmi_open_file_read(file);
515*c18ec02fSPetter Reinholdtsen 	if (fp == NULL)
516*c18ec02fSPetter Reinholdtsen 		return -1;
517*c18ec02fSPetter Reinholdtsen 
518*c18ec02fSPetter Reinholdtsen 	while (feof(fp) == 0) {
519*c18ec02fSPetter Reinholdtsen 		if (fgets(buf, 1024, fp) == NULL)
520*c18ec02fSPetter Reinholdtsen 			continue;
521*c18ec02fSPetter Reinholdtsen 
522*c18ec02fSPetter Reinholdtsen 		/* clip off optional comment tail indicated by # */
523*c18ec02fSPetter Reinholdtsen 		ptr = strchr(buf, '#');
524*c18ec02fSPetter Reinholdtsen 		if (ptr)
525*c18ec02fSPetter Reinholdtsen 			*ptr = '\0';
526*c18ec02fSPetter Reinholdtsen 		else
527*c18ec02fSPetter Reinholdtsen 			ptr = buf + strlen(buf);
528*c18ec02fSPetter Reinholdtsen 
529*c18ec02fSPetter Reinholdtsen 		/* clip off trailing and leading whitespace */
530*c18ec02fSPetter Reinholdtsen 		ptr--;
531*c18ec02fSPetter Reinholdtsen 		while (isspace((int)*ptr) && ptr >= buf)
532*c18ec02fSPetter Reinholdtsen 			*ptr-- = '\0';
533*c18ec02fSPetter Reinholdtsen 		ptr = buf;
534*c18ec02fSPetter Reinholdtsen 		while (isspace((int)*ptr))
535*c18ec02fSPetter Reinholdtsen 			ptr++;
536*c18ec02fSPetter Reinholdtsen 		if (strlen(ptr) == 0)
537*c18ec02fSPetter Reinholdtsen 			continue;
538*c18ec02fSPetter Reinholdtsen 
539*c18ec02fSPetter Reinholdtsen 		/* parse the event, 7 bytes with optional comment */
540*c18ec02fSPetter Reinholdtsen 		/* 0x00 0x00 0x00 0x00 0x00 0x00 0x00 # event */
541*c18ec02fSPetter Reinholdtsen 		i = 0;
542*c18ec02fSPetter Reinholdtsen 		tok = strtok(ptr, " ");
543*c18ec02fSPetter Reinholdtsen 		while (tok) {
544*c18ec02fSPetter Reinholdtsen 			if (i == 7)
545*c18ec02fSPetter Reinholdtsen 				break;
546*c18ec02fSPetter Reinholdtsen 			j = i++;
547*c18ec02fSPetter Reinholdtsen 			if (chmed == IPMI_CHANNEL_MEDIUM_SYSTEM)
548*c18ec02fSPetter Reinholdtsen 				j++;
549*c18ec02fSPetter Reinholdtsen 			rqdata[j] = (uint8_t)strtol(tok, NULL, 0);
550*c18ec02fSPetter Reinholdtsen 			tok = strtok(NULL, " ");
551*c18ec02fSPetter Reinholdtsen 		}
552*c18ec02fSPetter Reinholdtsen 		if (i < 7) {
553*c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "Invalid Event: %s",
554*c18ec02fSPetter Reinholdtsen 			       buf2str(rqdata, sizeof(rqdata)));
555*c18ec02fSPetter Reinholdtsen 			continue;
556*c18ec02fSPetter Reinholdtsen 		}
557*c18ec02fSPetter Reinholdtsen 
558*c18ec02fSPetter Reinholdtsen 		memset(&sel_event, 0, sizeof(struct sel_event_record));
559*c18ec02fSPetter Reinholdtsen 		sel_event.record_id = 0;
560*c18ec02fSPetter Reinholdtsen 		sel_event.sel_type.standard_type.gen_id = 2;
561*c18ec02fSPetter Reinholdtsen 
562*c18ec02fSPetter Reinholdtsen 		j = (chmed == IPMI_CHANNEL_MEDIUM_SYSTEM) ? 1 : 0;
563*c18ec02fSPetter Reinholdtsen 		sel_event.sel_type.standard_type.evm_rev = rqdata[j++];
564*c18ec02fSPetter Reinholdtsen 		sel_event.sel_type.standard_type.sensor_type = rqdata[j++];
565*c18ec02fSPetter Reinholdtsen 		sel_event.sel_type.standard_type.sensor_num = rqdata[j++];
566*c18ec02fSPetter Reinholdtsen 		sel_event.sel_type.standard_type.event_type = rqdata[j] & 0x7f;
567*c18ec02fSPetter Reinholdtsen 		sel_event.sel_type.standard_type.event_dir = (rqdata[j++] & 0x80) >> 7;
568*c18ec02fSPetter Reinholdtsen 		sel_event.sel_type.standard_type.event_data[0] = rqdata[j++];
569*c18ec02fSPetter Reinholdtsen 		sel_event.sel_type.standard_type.event_data[1] = rqdata[j++];
570*c18ec02fSPetter Reinholdtsen 		sel_event.sel_type.standard_type.event_data[2] = rqdata[j++];
571*c18ec02fSPetter Reinholdtsen 
572*c18ec02fSPetter Reinholdtsen 		ipmi_sel_print_std_entry(intf, &sel_event);
573*c18ec02fSPetter Reinholdtsen 
574*c18ec02fSPetter Reinholdtsen 		rsp = intf->sendrecv(intf, &req);
575*c18ec02fSPetter Reinholdtsen 		if (rsp == NULL) {
576*c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "Platform Event Message command failed");
577*c18ec02fSPetter Reinholdtsen 			rc = -1;
578*c18ec02fSPetter Reinholdtsen 		}
579*c18ec02fSPetter Reinholdtsen 		else if (rsp->ccode > 0) {
580*c18ec02fSPetter Reinholdtsen 			lprintf(LOG_ERR, "Platform Event Message command failed: %s",
581*c18ec02fSPetter Reinholdtsen 				val2str(rsp->ccode, completion_code_vals));
582*c18ec02fSPetter Reinholdtsen 			rc = -1;
583*c18ec02fSPetter Reinholdtsen 		}
584*c18ec02fSPetter Reinholdtsen 	}
585*c18ec02fSPetter Reinholdtsen 
586*c18ec02fSPetter Reinholdtsen 	fclose(fp);
587*c18ec02fSPetter Reinholdtsen 	return rc;
588*c18ec02fSPetter Reinholdtsen }
589*c18ec02fSPetter Reinholdtsen 
590*c18ec02fSPetter Reinholdtsen static void
ipmi_event_usage(void)591*c18ec02fSPetter Reinholdtsen ipmi_event_usage(void)
592*c18ec02fSPetter Reinholdtsen {
593*c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE, "");
594*c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE, "usage: event <num>");
595*c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE, "   Send generic test events");
596*c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE, "   1 : Temperature - Upper Critical - Going High");
597*c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE, "   2 : Voltage Threshold - Lower Critical - Going Low");
598*c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE, "   3 : Memory - Correctable ECC");
599*c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE, "");
600*c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE, "usage: event file <filename>");
601*c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE, "   Read and generate events from file");
602*c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE, "   Use the 'sel save' command to generate from SEL");
603*c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE, "");
604*c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE, "usage: event <sensorid> <state> [event_dir]");
605*c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE, "   sensorid  : Sensor ID string to use for event data");
606*c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE, "   state     : Sensor state, use 'list' to see possible states for sensor");
607*c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE, "   event_dir : assert, deassert [default=assert]");
608*c18ec02fSPetter Reinholdtsen 	lprintf(LOG_NOTICE, "");
609*c18ec02fSPetter Reinholdtsen }
610*c18ec02fSPetter Reinholdtsen 
611*c18ec02fSPetter Reinholdtsen int
ipmi_event_main(struct ipmi_intf * intf,int argc,char ** argv)612*c18ec02fSPetter Reinholdtsen ipmi_event_main(struct ipmi_intf * intf, int argc, char ** argv)
613*c18ec02fSPetter Reinholdtsen {
614*c18ec02fSPetter Reinholdtsen 	int rc = 0;
615*c18ec02fSPetter Reinholdtsen 
616*c18ec02fSPetter Reinholdtsen 	if (argc == 0 || strncmp(argv[0], "help", 4) == 0) {
617*c18ec02fSPetter Reinholdtsen 		ipmi_event_usage();
618*c18ec02fSPetter Reinholdtsen 		return 0;
619*c18ec02fSPetter Reinholdtsen 	}
620*c18ec02fSPetter Reinholdtsen 	if (strncmp(argv[0], "file", 4) == 0) {
621*c18ec02fSPetter Reinholdtsen 		if (argc < 2) {
622*c18ec02fSPetter Reinholdtsen 			ipmi_event_usage();
623*c18ec02fSPetter Reinholdtsen 			return 0;
624*c18ec02fSPetter Reinholdtsen 		}
625*c18ec02fSPetter Reinholdtsen 		return ipmi_event_fromfile(intf, argv[1]);
626*c18ec02fSPetter Reinholdtsen 	}
627*c18ec02fSPetter Reinholdtsen 	if (strlen(argv[0]) == 1) {
628*c18ec02fSPetter Reinholdtsen 		switch (argv[0][0]) {
629*c18ec02fSPetter Reinholdtsen 		case '1': return ipmi_send_platform_event_num(intf, 1);
630*c18ec02fSPetter Reinholdtsen 		case '2': return ipmi_send_platform_event_num(intf, 2);
631*c18ec02fSPetter Reinholdtsen 		case '3': return ipmi_send_platform_event_num(intf, 3);
632*c18ec02fSPetter Reinholdtsen 		}
633*c18ec02fSPetter Reinholdtsen 	}
634*c18ec02fSPetter Reinholdtsen 	if (argc < 2)
635*c18ec02fSPetter Reinholdtsen 		rc = ipmi_event_fromsensor(intf, argv[0], NULL, NULL);
636*c18ec02fSPetter Reinholdtsen 	else if (argc < 3)
637*c18ec02fSPetter Reinholdtsen 		rc = ipmi_event_fromsensor(intf, argv[0], argv[1], NULL);
638*c18ec02fSPetter Reinholdtsen 	else
639*c18ec02fSPetter Reinholdtsen 		rc = ipmi_event_fromsensor(intf, argv[0], argv[1], argv[2]);
640*c18ec02fSPetter Reinholdtsen 
641*c18ec02fSPetter Reinholdtsen 	return rc;
642*c18ec02fSPetter Reinholdtsen }
643