1 /*
2  * dump_sensors.c
3  *
4  * OpenIPMI test code
5  *
6  * Author: Corey Minyard <minyard@acm.org>
7  *
8  *  This program is free software; you can redistribute it and/or
9  *  modify it under the terms of the GNU Lesser General Public License
10  *  as published by the Free Software Foundation; either version 2 of
11  *  the License, or (at your option) any later version.
12  *
13  *
14  *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
15  *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16  *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17  *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
19  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
20  *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21  *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
22  *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
23  *  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  *
25  *  You should have received a copy of the GNU Lesser General Public
26  *  License along with this program; if not, write to the Free
27  *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28  */
29 
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <sys/types.h>
34 #include <sys/stat.h>
35 #include <fcntl.h>
36 #include <unistd.h>
37 #include <netdb.h>
38 #include <ctype.h>
39 #include <time.h>
40 
41 #include <OpenIPMI/ipmiif.h>
42 #include <OpenIPMI/ipmi_smi.h>
43 #include <OpenIPMI/ipmi_err.h>
44 #include <OpenIPMI/ipmi_auth.h>
45 #include <OpenIPMI/ipmi_lan.h>
46 #include <OpenIPMI/ipmi_posix.h>
47 #include <OpenIPMI/ipmi_fru.h>
48 
49 #include <OpenIPMI/internal/ipmi_sensor.h>
50 
51 static const char *progname;
52 
con_usage(const char * name,const char * help,void * cb_data)53 static void con_usage(const char *name, const char *help, void *cb_data)
54 {
55     printf("\n%s%s", name, help);
56 }
57 
58 static void
usage(void)59 usage(void)
60 {
61     printf("Usage:\n");
62     printf(" %s <con_parms>\n", progname);
63     printf(" Where <con_parms> is one of:");
64     ipmi_parse_args_iter_help(con_usage, NULL);
65 }
66 
67 static int done;
68 
69 /* Whenever the status of a sensor changes, the function is called
70    We display the information of the sensor if we find a new sensor
71 */
72 static void
sensor_change(enum ipmi_update_e op,ipmi_entity_t * ent,ipmi_sensor_t * sensor,void * cb_data)73 sensor_change(enum ipmi_update_e op,
74 	      ipmi_entity_t      *ent,
75 	      ipmi_sensor_t      *sensor,
76 	      void               *cb_data)
77 {
78     int id, instance;
79     char name[33];
80 
81     id = ipmi_entity_get_entity_id(ent);
82     instance = ipmi_entity_get_entity_instance(ent);
83     ipmi_sensor_get_id(sensor, name, 32);
84     if (op == IPMI_ADDED) {
85 	int lun, num;
86 	printf("Sensor added: %d.%d.%s\n", id, instance, name);
87 	ipmi_sensor_get_num(sensor, &lun, &num);
88 	printf("  owner:   %d\n", ipmi_sensor_get_owner(sensor));
89 	printf("  channel: %d\n", ipmi_sensor_get_channel(sensor));
90 	printf("  lun:     %d\n", lun);
91 	printf("  num:     %d\n", num);
92     }
93 }
94 
95 /* Whenever the status of an entity changes, the function is called
96    When a new entity is created, we search all sensors that belong
97    to the entity */
98 static void
entity_change(enum ipmi_update_e op,ipmi_domain_t * domain,ipmi_entity_t * entity,void * cb_data)99 entity_change(enum ipmi_update_e op,
100 	      ipmi_domain_t      *domain,
101 	      ipmi_entity_t      *entity,
102 	      void               *cb_data)
103 {
104     int rv;
105     int id, instance;
106 
107     id = ipmi_entity_get_entity_id(entity);
108     instance = ipmi_entity_get_entity_instance(entity);
109     if (op == IPMI_ADDED) {
110 	printf("Entity added: %d.%d\n", id, instance);
111 	/* Register callback so that when the status of a
112 	   sensor changes, sensor_change is called */
113 	rv = ipmi_entity_add_sensor_update_handler(entity,
114 						   sensor_change,
115 						   entity);
116 	if (rv) {
117 	    printf("ipmi_entity_set_sensor_update_handler: 0x%x", rv);
118 	    exit(1);
119 	}
120     }
121 }
122 
123 /* After we have established connection to domain, this function get called
124    At this time, we can do whatever things we want to do. Herr we want to
125    search all entities in the system */
126 void
setup_done(ipmi_domain_t * domain,int err,unsigned int conn_num,unsigned int port_num,int still_connected,void * user_data)127 setup_done(ipmi_domain_t *domain,
128 	   int           err,
129 	   unsigned int  conn_num,
130 	   unsigned int  port_num,
131 	   int           still_connected,
132 	   void          *user_data)
133 {
134     int rv;
135 
136     /* Register a callback function entity_change. When a new entities
137        is created, entity_change is called */
138     rv = ipmi_domain_add_entity_update_handler(domain, entity_change, domain);
139     if (rv) {
140 	printf("ipmi_domain_add_entity_update_handler return error: %d\n", rv);
141 	return;
142     }
143 
144 }
145 
146 static void
domain_closed(void * cb_data)147 domain_closed(void *cb_data)
148 {
149     done = 1;
150 }
151 
152 static void
domain_up(ipmi_domain_t * domain,void * cb_data)153 domain_up(ipmi_domain_t *domain, void *cb_data)
154 {
155     int rv;
156 
157     rv = ipmi_domain_close(domain, domain_closed, NULL);
158     if (rv) {
159 	printf("ipmi_domain_close return error: %d\n", rv);
160 	exit(1);
161     }
162 }
163 
164 static os_handler_t *os_hnd;
165 
166 static void
my_vlog(os_handler_t * handler,const char * format,enum ipmi_log_type_e log_type,va_list ap)167 my_vlog(os_handler_t         *handler,
168 	const char           *format,
169 	enum ipmi_log_type_e log_type,
170 	va_list              ap)
171 {
172     int do_nl = 1;
173 
174     switch(log_type)
175     {
176 	case IPMI_LOG_INFO:
177 	    printf("INFO: ");
178 	    break;
179 
180 	case IPMI_LOG_WARNING:
181 	    printf("WARN: ");
182 	    break;
183 
184 	case IPMI_LOG_SEVERE:
185 	    printf("SEVR: ");
186 	    break;
187 
188 	case IPMI_LOG_FATAL:
189 	    printf("FATL: ");
190 	    break;
191 
192 	case IPMI_LOG_ERR_INFO:
193 	    printf("EINF: ");
194 	    break;
195 
196 	case IPMI_LOG_DEBUG_START:
197 	    do_nl = 0;
198 	    /* FALLTHROUGH */
199 	case IPMI_LOG_DEBUG:
200 	    printf("DEBG: ");
201 	    break;
202 
203 	case IPMI_LOG_DEBUG_CONT:
204 	    do_nl = 0;
205 	    /* FALLTHROUGH */
206 	case IPMI_LOG_DEBUG_END:
207 	    break;
208     }
209 
210     vprintf(format, ap);
211 
212     if (do_nl)
213 	printf("\n");
214 }
215 
216 int
main(int argc,char * argv[])217 main(int argc, char *argv[])
218 {
219     int         rv;
220     int         curr_arg = 1;
221     ipmi_args_t *args;
222     ipmi_con_t  *con;
223 
224     progname = argv[0];
225 
226     /* OS handler allocated first. */
227     os_hnd = ipmi_posix_setup_os_handler();
228     if (!os_hnd) {
229 	printf("ipmi_smi_setup_con: Unable to allocate os handler\n");
230 	exit(1);
231     }
232 
233     /* Override the default log handler (just to show how). */
234     os_hnd->set_log_handler(os_hnd, my_vlog);
235 
236     /* Initialize the OpenIPMI library. */
237     ipmi_init(os_hnd);
238 
239     rv = ipmi_parse_args2(&curr_arg, argc, argv, &args);
240     if (rv) {
241 	fprintf(stderr, "Error parsing command arguments, argument %d: %s\n",
242 		curr_arg, strerror(rv));
243 	usage();
244 	exit(1);
245     }
246 
247     rv = ipmi_args_setup_con(args, os_hnd, NULL, &con);
248     if (rv) {
249         fprintf(stderr, "ipmi_ip_setup_con: %s", strerror(rv));
250 	exit(1);
251     }
252 
253     rv = ipmi_open_domain("", &con, 1, setup_done, NULL, domain_up, NULL,
254 			  NULL, 0, NULL);
255     if (rv) {
256 	fprintf(stderr, "ipmi_init_domain: %s\n", strerror(rv));
257 	exit(1);
258     }
259 
260     /* We run the select loop here, this shows how you can use
261        sel_select.  You could add your own processing in this loop. */
262     while (!done)
263 	os_hnd->perform_one_op(os_hnd, NULL);
264 
265     os_hnd->free_os_handler(os_hnd);
266 
267     return 0;
268 }
269