~ubuntu-branches/ubuntu/trusty/openipmi/trusty-updates

« back to all changes in this revision

Viewing changes to sample/waiter_sample.c

  • Committer: Bazaar Package Importer
  • Author(s): Noèl Köthe
  • Date: 2009-07-28 10:17:23 UTC
  • mfrom: (1.2.3 upstream)
  • mto: This revision was merged to the branch mainline in revision 16.
  • Revision ID: james.westby@ubuntu.com-20090728101723-qxfi37j3g2l9dv6n
Tags: 2.0.16-1
* new upstream release from 2009-03-16
* debian/compat debian/control raised to debhelper 5
* debian/control removed URL in description new we
  have the Homepage: field
* debian/control updated Standards-Version: (no changes needed)
* debian/rules removed unused cdbd dependency

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * waiter_sample.c
 
3
 *
 
4
 * OpenIPMI test code how to use OS handler waiters for blocking 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
 
 
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
 
51
   structures. */
 
52
 
 
53
static const char *progname;
 
54
 
 
55
#define MAX_SENSORS 128
 
56
 
 
57
struct waiter_data
 
58
{
 
59
    os_handler_waiter_t *waiter;
 
60
    int err;
 
61
    ipmi_sensor_id_t sensors[MAX_SENSORS];
 
62
    int sensors_type[MAX_SENSORS];
 
63
    unsigned int num_sensors;
 
64
    unsigned int curr;
 
65
 
 
66
    /* values from a threshold sensor. */
 
67
    enum ipmi_value_present_e value_present;
 
68
    unsigned int              raw_value;
 
69
    double                    val;
 
70
 
 
71
    /* values from a discrete and a threshold sensor */
 
72
    ipmi_states_t *states;
 
73
};
 
74
 
 
75
void
 
76
setup_done(ipmi_domain_t *domain,
 
77
           int           err,
 
78
           unsigned int  conn_num,
 
79
           unsigned int  port_num,
 
80
           int           still_connected,
 
81
           void          *cb_data)
 
82
{
 
83
    struct waiter_data *wd = cb_data;
 
84
 
 
85
    if (err) {
 
86
        wd->err = err;
 
87
        os_handler_waiter_release(wd->waiter);
 
88
    }
 
89
}
 
90
 
 
91
void
 
92
fully_up(ipmi_domain_t *domain, void *cb_data)
 
93
{
 
94
    struct waiter_data *wd = cb_data;
 
95
 
 
96
    wd->err = 0;
 
97
    os_handler_waiter_release(wd->waiter);
 
98
}
 
99
 
 
100
void
 
101
sensor_handler(ipmi_entity_t *entity, ipmi_sensor_t *sensor, void *cb_data)
 
102
{
 
103
    struct waiter_data *wd = cb_data;
 
104
 
 
105
    if (wd->num_sensors >= MAX_SENSORS)
 
106
        return;
 
107
 
 
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);
 
111
 
 
112
    wd->num_sensors++;
 
113
}
 
114
 
 
115
void
 
116
entity_iterate_sensors(ipmi_entity_t *entity, void *cb_data)
 
117
{
 
118
    ipmi_entity_iterate_sensors(entity, sensor_handler, cb_data);
 
119
}
 
120
 
 
121
void
 
122
domain_iterate_entities(ipmi_domain_t *domain, void *cb_data)
 
123
{
 
124
    ipmi_domain_iterate_entities(domain, entity_iterate_sensors, cb_data);
 
125
}
 
126
 
 
127
void
 
128
close_done(void *cb_data)
 
129
{
 
130
    struct waiter_data *wd = cb_data;
 
131
 
 
132
    os_handler_waiter_release(wd->waiter);
 
133
}
 
134
 
 
135
void
 
136
domain_close(ipmi_domain_t *domain, void *cb_data)
 
137
{
 
138
    struct waiter_data *wd = cb_data;
 
139
 
 
140
    wd->err = ipmi_domain_close(domain, close_done, cb_data);
 
141
    if (wd->err)
 
142
        os_handler_waiter_release(wd->waiter);
 
143
}
 
144
 
 
145
static void
 
146
handle_sensor_reading(ipmi_sensor_t             *sensor,
 
147
                      int                       err,
 
148
                      enum ipmi_value_present_e value_present,
 
149
                      unsigned int              raw_value,
 
150
                      double                    val,
 
151
                      ipmi_states_t             *states,
 
152
                      void                      *cb_data)
 
153
{
 
154
    struct waiter_data *wd = cb_data;
 
155
    enum ipmi_thresh_e thresh;
 
156
    char name[IPMI_SENSOR_NAME_LEN];
 
157
 
 
158
    ipmi_sensor_get_name(sensor, name, sizeof(name));
 
159
    if (err) {
 
160
        printf("Error 0x%x getting discrete states for sensor %s\n",
 
161
               err, name);
 
162
        goto out;
 
163
    }
 
164
 
 
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");
 
172
 
 
173
    switch (value_present)
 
174
    {
 
175
    case IPMI_NO_VALUES_PRESENT:
 
176
        printf("  no value present\n");
 
177
        break;
 
178
    case IPMI_BOTH_VALUES_PRESENT:
 
179
        {
 
180
            const char *percent = "";
 
181
            const char *base;
 
182
            const char *mod_use = "";
 
183
            const char *modifier = "";
 
184
            const char *rate;
 
185
 
 
186
            base = ipmi_sensor_get_base_unit_string(sensor);
 
187
            if (ipmi_sensor_get_percentage(sensor))
 
188
                percent = "%";
 
189
            switch (ipmi_sensor_get_modifier_unit_use(sensor)) {
 
190
            case IPMI_MODIFIER_UNIT_NONE:
 
191
                break;
 
192
            case IPMI_MODIFIER_UNIT_BASE_DIV_MOD:
 
193
                mod_use = "/";
 
194
                modifier = ipmi_sensor_get_modifier_unit_string(sensor);
 
195
                break;
 
196
            case IPMI_MODIFIER_UNIT_BASE_MULT_MOD:
 
197
                mod_use = "*";
 
198
                modifier = ipmi_sensor_get_modifier_unit_string(sensor);
 
199
                break;
 
200
            }
 
201
            rate = ipmi_sensor_get_rate_unit_string(sensor);
 
202
            
 
203
            printf("  value: %lf%s %s%s%s%s\n", val, percent,
 
204
                   base, mod_use, modifier, rate);
 
205
        }
 
206
        /* FALLTHROUGH */
 
207
    case IPMI_RAW_VALUE_PRESENT:
 
208
        printf("  raw value: 0x%2.2x\n", raw_value);
 
209
    }
 
210
 
 
211
    if (ipmi_sensor_get_threshold_access(sensor)
 
212
        == IPMI_THRESHOLD_ACCESS_SUPPORT_NONE)
 
213
        goto out;
 
214
 
 
215
    for (thresh=IPMI_LOWER_NON_CRITICAL;
 
216
         thresh<=IPMI_UPPER_NON_RECOVERABLE;
 
217
         thresh++)
 
218
    {
 
219
        int val, rv;
 
220
 
 
221
        rv = ipmi_sensor_threshold_reading_supported(sensor, thresh, &val);
 
222
        if (rv || !val)
 
223
            continue;
 
224
 
 
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));
 
228
        else
 
229
            printf("  Threshold %s is in range\n",
 
230
                   ipmi_get_threshold_string(thresh));
 
231
    }
 
232
 
 
233
 out:
 
234
    os_handler_waiter_release(wd->waiter);
 
235
}
 
236
 
 
237
static void
 
238
handle_sensor_states(ipmi_sensor_t *sensor,
 
239
                     int           err,
 
240
                     ipmi_states_t *states,
 
241
                     void          *cb_data)
 
242
{
 
243
    struct waiter_data *wd = cb_data;
 
244
    int  i;
 
245
    char name[IPMI_SENSOR_NAME_LEN];
 
246
 
 
247
    ipmi_sensor_get_name(sensor, name, sizeof(name));
 
248
    if (err) {
 
249
        printf("Error 0x%x getting discrete states for sensor %s\n",
 
250
               err, name);
 
251
        goto out;
 
252
    }
 
253
 
 
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");
 
261
 
 
262
    for (i=0; i<15; i++) {
 
263
        int val, rv;
 
264
 
 
265
        rv = ipmi_sensor_discrete_event_readable(sensor, i, &val);
 
266
        if (rv || !val)
 
267
            continue;
 
268
 
 
269
        printf("  state %d value is %d\n", i, ipmi_is_state_set(states, i));
 
270
    }
 
271
 
 
272
 out:
 
273
    os_handler_waiter_release(wd->waiter);
 
274
}
 
275
 
 
276
int
 
277
main(int argc, char *argv[])
 
278
{
 
279
    int         rv;
 
280
    int         curr_arg = 1;
 
281
    ipmi_args_t *args;
 
282
    ipmi_con_t  *con;
 
283
    os_handler_waiter_factory_t *waiterf;
 
284
    os_handler_t *os_hnd;
 
285
    char        ebuf[128];
 
286
    ipmi_domain_id_t domain_id;
 
287
 
 
288
 
 
289
    /*
 
290
     * We can do this without dynamic allocation because this function will
 
291
     * never be exited until the progran is done.
 
292
     */
 
293
    struct waiter_data waiter_space;
 
294
    struct waiter_data *wd = &waiter_space;
 
295
 
 
296
    progname = argv[0];
 
297
 
 
298
    /* OS handler allocated first. */
 
299
    os_hnd = ipmi_posix_setup_os_handler();
 
300
    if (!os_hnd) {
 
301
        printf("ipmi_smi_setup_con: Unable to allocate os handler\n");
 
302
        exit(1);
 
303
    }
 
304
 
 
305
    /* Use the default log handler. */
 
306
 
 
307
    /* Initialize the OpenIPMI library. */
 
308
    ipmi_init(os_hnd);
 
309
 
 
310
    rv = ipmi_parse_args2(&curr_arg, argc, argv, &args);
 
311
    if (rv) {
 
312
        fprintf(stderr, "Error parsing command arguments, argument %d: %s\n",
 
313
                curr_arg, ipmi_get_error_string(rv, ebuf, sizeof(ebuf)));
 
314
        exit(1);
 
315
    }
 
316
 
 
317
    rv = ipmi_args_setup_con(args, os_hnd, NULL, &con);
 
318
    if (rv) {
 
319
        fprintf(stderr, "ipmi_ip_setup_con: %s",
 
320
                ipmi_get_error_string(rv, ebuf, sizeof(ebuf)));
 
321
        exit(1);
 
322
    }
 
323
 
 
324
    rv = os_handler_alloc_waiter_factory(os_hnd, 0, 0, &waiterf);
 
325
    if (rv) {
 
326
        fprintf(stderr, "os_handler_alloc_waiter_factory: %s",
 
327
                ipmi_get_error_string(rv, ebuf, sizeof(ebuf)));
 
328
        exit(1);
 
329
    }
 
330
 
 
331
    wd->num_sensors = 0;
 
332
    wd->waiter = os_handler_alloc_waiter(waiterf);
 
333
    if (!wd->waiter) {
 
334
        fprintf(stderr, "os_handler_alloc_waiter: Out of memory");
 
335
        exit(1);
 
336
    }
 
337
 
 
338
    rv = ipmi_open_domain("", &con, 1, setup_done, wd, fully_up, wd,
 
339
                          NULL, 0, &domain_id);
 
340
    if (rv) {
 
341
        fprintf(stderr, "ipmi_init_domain: %s\n",
 
342
                ipmi_get_error_string(rv, ebuf, sizeof(ebuf)));
 
343
        exit(1);
 
344
    }
 
345
 
 
346
    os_handler_waiter_wait(wd->waiter, NULL);
 
347
    if (wd->err) {
 
348
        fprintf(stderr, "Error starting connection: %s\n", 
 
349
                ipmi_get_error_string(wd->err, ebuf, sizeof(ebuf)));
 
350
    }
 
351
 
 
352
    /*
 
353
     * At this point the domain is fully up.  We can iterate the
 
354
     * sensors now.  First get a list of all sensor ids.
 
355
     */
 
356
    ipmi_domain_pointer_cb(domain_id, domain_iterate_entities, wd);
 
357
 
 
358
    /*
 
359
     * Now scan the sensors
 
360
     */
 
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);
 
366
        else
 
367
            rv = ipmi_sensor_id_get_states(wd->sensors[wd->curr],
 
368
                                           handle_sensor_states, wd);
 
369
        if (rv) {
 
370
            fprintf(stderr, "Error reading sensor: %s\n",
 
371
                    ipmi_get_error_string(rv, ebuf, sizeof(ebuf)));
 
372
            continue;
 
373
        }
 
374
        os_handler_waiter_wait(wd->waiter, NULL);
 
375
    }
 
376
 
 
377
    wd->err = 0;
 
378
    os_handler_waiter_use(wd->waiter);
 
379
    rv = ipmi_domain_pointer_cb(domain_id, domain_close, wd);
 
380
    if (rv) {
 
381
        fprintf(stderr, "close ptr cb: %s\n",
 
382
                ipmi_get_error_string(rv, ebuf, sizeof(ebuf)));
 
383
        exit(1);
 
384
    }
 
385
    os_handler_waiter_wait(wd->waiter, NULL);
 
386
    if (wd->err) {
 
387
        fprintf(stderr, "ipmi_domain_close: %s\n", 
 
388
                ipmi_get_error_string(wd->err, ebuf, sizeof(ebuf)));
 
389
    }
 
390
 
 
391
    /* Technically, we can't get here, but this is an example. */
 
392
    os_hnd->free_os_handler(os_hnd);
 
393
    return 0;
 
394
}