4
* OpenIPMI test code how to use OS handler waiters for blocking code.
6
* Author: Corey Minyard <minyard@acm.org>
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.
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.
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.
33
#include <sys/types.h>
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>
48
/* This sample application demostrates some general handling of sensors,
49
like reading values, setting up events, and things of that nature.
50
It also demonstrates some good coding practices like refcounting
53
static const char *progname;
55
#define MAX_SENSORS 128
59
os_handler_waiter_t *waiter;
61
ipmi_sensor_id_t sensors[MAX_SENSORS];
62
int sensors_type[MAX_SENSORS];
63
unsigned int num_sensors;
66
/* values from a threshold sensor. */
67
enum ipmi_value_present_e value_present;
68
unsigned int raw_value;
71
/* values from a discrete and a threshold sensor */
72
ipmi_states_t *states;
76
setup_done(ipmi_domain_t *domain,
78
unsigned int conn_num,
79
unsigned int port_num,
83
struct waiter_data *wd = cb_data;
87
os_handler_waiter_release(wd->waiter);
92
fully_up(ipmi_domain_t *domain, void *cb_data)
94
struct waiter_data *wd = cb_data;
97
os_handler_waiter_release(wd->waiter);
101
sensor_handler(ipmi_entity_t *entity, ipmi_sensor_t *sensor, void *cb_data)
103
struct waiter_data *wd = cb_data;
105
if (wd->num_sensors >= MAX_SENSORS)
108
wd->sensors[wd->num_sensors] = ipmi_sensor_convert_to_id(sensor);
109
wd->sensors_type[wd->num_sensors]
110
= ipmi_sensor_get_event_reading_type(sensor);
116
entity_iterate_sensors(ipmi_entity_t *entity, void *cb_data)
118
ipmi_entity_iterate_sensors(entity, sensor_handler, cb_data);
122
domain_iterate_entities(ipmi_domain_t *domain, void *cb_data)
124
ipmi_domain_iterate_entities(domain, entity_iterate_sensors, cb_data);
128
close_done(void *cb_data)
130
struct waiter_data *wd = cb_data;
132
os_handler_waiter_release(wd->waiter);
136
domain_close(ipmi_domain_t *domain, void *cb_data)
138
struct waiter_data *wd = cb_data;
140
wd->err = ipmi_domain_close(domain, close_done, cb_data);
142
os_handler_waiter_release(wd->waiter);
146
handle_sensor_reading(ipmi_sensor_t *sensor,
148
enum ipmi_value_present_e value_present,
149
unsigned int raw_value,
151
ipmi_states_t *states,
154
struct waiter_data *wd = cb_data;
155
enum ipmi_thresh_e thresh;
156
char name[IPMI_SENSOR_NAME_LEN];
158
ipmi_sensor_get_name(sensor, name, sizeof(name));
160
printf("Error 0x%x getting discrete states for sensor %s\n",
165
printf("Got threshold reading for sensor %s\n", name);
166
if (ipmi_is_event_messages_enabled(states))
167
printf(" event messages enabled\n");
168
if (ipmi_is_sensor_scanning_enabled(states))
169
printf(" sensor scanning enabled\n");
170
if (ipmi_is_initial_update_in_progress(states))
171
printf(" initial update in progress\n");
173
switch (value_present)
175
case IPMI_NO_VALUES_PRESENT:
176
printf(" no value present\n");
178
case IPMI_BOTH_VALUES_PRESENT:
180
const char *percent = "";
182
const char *mod_use = "";
183
const char *modifier = "";
186
base = ipmi_sensor_get_base_unit_string(sensor);
187
if (ipmi_sensor_get_percentage(sensor))
189
switch (ipmi_sensor_get_modifier_unit_use(sensor)) {
190
case IPMI_MODIFIER_UNIT_NONE:
192
case IPMI_MODIFIER_UNIT_BASE_DIV_MOD:
194
modifier = ipmi_sensor_get_modifier_unit_string(sensor);
196
case IPMI_MODIFIER_UNIT_BASE_MULT_MOD:
198
modifier = ipmi_sensor_get_modifier_unit_string(sensor);
201
rate = ipmi_sensor_get_rate_unit_string(sensor);
203
printf(" value: %lf%s %s%s%s%s\n", val, percent,
204
base, mod_use, modifier, rate);
207
case IPMI_RAW_VALUE_PRESENT:
208
printf(" raw value: 0x%2.2x\n", raw_value);
211
if (ipmi_sensor_get_threshold_access(sensor)
212
== IPMI_THRESHOLD_ACCESS_SUPPORT_NONE)
215
for (thresh=IPMI_LOWER_NON_CRITICAL;
216
thresh<=IPMI_UPPER_NON_RECOVERABLE;
221
rv = ipmi_sensor_threshold_reading_supported(sensor, thresh, &val);
225
if (ipmi_is_threshold_out_of_range(states, thresh))
226
printf(" Threshold %s is out of range\n",
227
ipmi_get_threshold_string(thresh));
229
printf(" Threshold %s is in range\n",
230
ipmi_get_threshold_string(thresh));
234
os_handler_waiter_release(wd->waiter);
238
handle_sensor_states(ipmi_sensor_t *sensor,
240
ipmi_states_t *states,
243
struct waiter_data *wd = cb_data;
245
char name[IPMI_SENSOR_NAME_LEN];
247
ipmi_sensor_get_name(sensor, name, sizeof(name));
249
printf("Error 0x%x getting discrete states for sensor %s\n",
254
printf("Got state reading for sensor %s\n", name);
255
if (ipmi_is_event_messages_enabled(states))
256
printf(" event messages enabled\n");
257
if (ipmi_is_sensor_scanning_enabled(states))
258
printf(" sensor scanning enabled\n");
259
if (ipmi_is_initial_update_in_progress(states))
260
printf(" initial update in progress\n");
262
for (i=0; i<15; i++) {
265
rv = ipmi_sensor_discrete_event_readable(sensor, i, &val);
269
printf(" state %d value is %d\n", i, ipmi_is_state_set(states, i));
273
os_handler_waiter_release(wd->waiter);
277
main(int argc, char *argv[])
283
os_handler_waiter_factory_t *waiterf;
284
os_handler_t *os_hnd;
286
ipmi_domain_id_t domain_id;
290
* We can do this without dynamic allocation because this function will
291
* never be exited until the progran is done.
293
struct waiter_data waiter_space;
294
struct waiter_data *wd = &waiter_space;
298
/* OS handler allocated first. */
299
os_hnd = ipmi_posix_setup_os_handler();
301
printf("ipmi_smi_setup_con: Unable to allocate os handler\n");
305
/* Use the default log handler. */
307
/* Initialize the OpenIPMI library. */
310
rv = ipmi_parse_args2(&curr_arg, argc, argv, &args);
312
fprintf(stderr, "Error parsing command arguments, argument %d: %s\n",
313
curr_arg, ipmi_get_error_string(rv, ebuf, sizeof(ebuf)));
317
rv = ipmi_args_setup_con(args, os_hnd, NULL, &con);
319
fprintf(stderr, "ipmi_ip_setup_con: %s",
320
ipmi_get_error_string(rv, ebuf, sizeof(ebuf)));
324
rv = os_handler_alloc_waiter_factory(os_hnd, 0, 0, &waiterf);
326
fprintf(stderr, "os_handler_alloc_waiter_factory: %s",
327
ipmi_get_error_string(rv, ebuf, sizeof(ebuf)));
332
wd->waiter = os_handler_alloc_waiter(waiterf);
334
fprintf(stderr, "os_handler_alloc_waiter: Out of memory");
338
rv = ipmi_open_domain("", &con, 1, setup_done, wd, fully_up, wd,
339
NULL, 0, &domain_id);
341
fprintf(stderr, "ipmi_init_domain: %s\n",
342
ipmi_get_error_string(rv, ebuf, sizeof(ebuf)));
346
os_handler_waiter_wait(wd->waiter, NULL);
348
fprintf(stderr, "Error starting connection: %s\n",
349
ipmi_get_error_string(wd->err, ebuf, sizeof(ebuf)));
353
* At this point the domain is fully up. We can iterate the
354
* sensors now. First get a list of all sensor ids.
356
ipmi_domain_pointer_cb(domain_id, domain_iterate_entities, wd);
359
* Now scan the sensors
361
for (wd->curr = 0; wd->curr < wd->num_sensors; wd->curr++) {
362
os_handler_waiter_use(wd->waiter);
363
if (wd->sensors_type[wd->curr] == IPMI_EVENT_READING_TYPE_THRESHOLD)
364
rv = ipmi_sensor_id_get_reading(wd->sensors[wd->curr],
365
handle_sensor_reading, wd);
367
rv = ipmi_sensor_id_get_states(wd->sensors[wd->curr],
368
handle_sensor_states, wd);
370
fprintf(stderr, "Error reading sensor: %s\n",
371
ipmi_get_error_string(rv, ebuf, sizeof(ebuf)));
374
os_handler_waiter_wait(wd->waiter, NULL);
378
os_handler_waiter_use(wd->waiter);
379
rv = ipmi_domain_pointer_cb(domain_id, domain_close, wd);
381
fprintf(stderr, "close ptr cb: %s\n",
382
ipmi_get_error_string(rv, ebuf, sizeof(ebuf)));
385
os_handler_waiter_wait(wd->waiter, NULL);
387
fprintf(stderr, "ipmi_domain_close: %s\n",
388
ipmi_get_error_string(wd->err, ebuf, sizeof(ebuf)));
391
/* Technically, we can't get here, but this is an example. */
392
os_hnd->free_os_handler(os_hnd);