1 /*
2 * cmd_control.c
3 *
4 * A command interpreter for OpenIPMI
5 *
6 * Author: MontaVista Software, Inc.
7 * Corey Minyard <minyard@mvista.com>
8 * source@mvista.com
9 *
10 * Copyright 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 <errno.h>
35 #include <string.h>
36 #include <ctype.h>
37 #include <stdlib.h>
38 #include <stdio.h>
39 #include <OpenIPMI/ipmiif.h>
40 #include <OpenIPMI/ipmi_cmdlang.h>
41
42 /* Internal includes, do not use in your programs */
43 #include <OpenIPMI/internal/ipmi_malloc.h>
44
45 static void
control_list_handler(ipmi_entity_t * entity,ipmi_control_t * control,void * cb_data)46 control_list_handler(ipmi_entity_t *entity, ipmi_control_t *control,
47 void *cb_data)
48 {
49 ipmi_cmd_info_t *cmd_info = cb_data;
50 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
51 char control_name[IPMI_CONTROL_NAME_LEN];
52
53 if (cmdlang->err)
54 return;
55
56 ipmi_control_get_name(control, control_name, sizeof(control_name));
57
58 ipmi_cmdlang_out(cmd_info, "Name", control_name);
59 }
60
61 static void
control_list(ipmi_entity_t * entity,void * cb_data)62 control_list(ipmi_entity_t *entity, void *cb_data)
63 {
64 ipmi_cmd_info_t *cmd_info = cb_data;
65 char entity_name[IPMI_ENTITY_NAME_LEN];
66
67 ipmi_entity_get_name(entity, entity_name, sizeof(entity_name));
68 ipmi_cmdlang_out(cmd_info, "Entity", NULL);
69 ipmi_cmdlang_down(cmd_info);
70 ipmi_cmdlang_out(cmd_info, "Name", entity_name);
71 ipmi_cmdlang_out(cmd_info, "Controls", NULL);
72 ipmi_cmdlang_down(cmd_info);
73 ipmi_entity_iterate_controls(entity, control_list_handler, cmd_info);
74 ipmi_cmdlang_up(cmd_info);
75 ipmi_cmdlang_up(cmd_info);
76 }
77
78 static void
control_dump(ipmi_control_t * control,ipmi_cmd_info_t * cmd_info)79 control_dump(ipmi_control_t *control, ipmi_cmd_info_t *cmd_info)
80 {
81 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
82 int num;
83 char *str;
84 int len;
85 int val, val2, val3;
86 int i, j, k;
87
88 ipmi_cmdlang_out(cmd_info, "Type", ipmi_control_get_type_string(control));
89 ipmi_cmdlang_out_bool(cmd_info, "Generates events",
90 ipmi_control_has_events(control));
91 ipmi_cmdlang_out_bool(cmd_info, "Settable",
92 ipmi_control_is_settable(control));
93 ipmi_cmdlang_out_bool(cmd_info, "Readable",
94 ipmi_control_is_readable(control));
95 num = ipmi_control_get_num_vals(control);
96 ipmi_cmdlang_out_int(cmd_info, "Num Values", num);
97 len = ipmi_control_get_id_length(control);
98 if (len) {
99 str = ipmi_mem_alloc(len);
100 if (!str) {
101 cmdlang->err = ENOMEM;
102 cmdlang->errstr = "Out of memory";
103 goto out_err;
104 }
105 len = ipmi_control_get_id(control, str, len);
106 ipmi_cmdlang_out_type(cmd_info, "Id",
107 ipmi_control_get_id_type(control),
108 str, len);
109 ipmi_mem_free(str);
110 }
111
112 switch (ipmi_control_get_type(control)) {
113 case IPMI_CONTROL_LIGHT:
114 val = ipmi_control_light_set_with_setting(control);
115 if (val) {
116 ipmi_cmdlang_out(cmd_info, "Set with", "settings");
117 for (j=0; j<num; j++) {
118 ipmi_cmdlang_out(cmd_info, "Light", NULL);
119 ipmi_cmdlang_down(cmd_info);
120 ipmi_cmdlang_out_int(cmd_info, "Number", j);
121 val = ipmi_control_light_has_loc_ctrl(control, j);
122 ipmi_cmdlang_out_bool(cmd_info, "Local Control", val);
123 for (i=IPMI_CONTROL_COLOR_BLACK;
124 i<IPMI_CONTROL_COLOR_ORANGE;
125 i++)
126 {
127 val = ipmi_control_light_is_color_sup(control, j, i);
128 if (val)
129 ipmi_cmdlang_out(cmd_info, "Color",
130 ipmi_get_color_string(i));
131 }
132 ipmi_cmdlang_up(cmd_info);
133 }
134 } else {
135 ipmi_cmdlang_out(cmd_info, "Set with", "transitions");
136 for (i=0; i<num; i++) {
137 ipmi_cmdlang_out(cmd_info, "Light", NULL);
138 ipmi_cmdlang_down(cmd_info);
139 ipmi_cmdlang_out_int(cmd_info, "Number", i);
140 val = ipmi_control_get_num_light_values(control, i);
141 ipmi_cmdlang_out_int(cmd_info, "Num Values", val);
142 for (j=0; j<val; j++) {
143 ipmi_cmdlang_out(cmd_info, "Value", NULL);
144 ipmi_cmdlang_down(cmd_info);
145 ipmi_cmdlang_out_int(cmd_info, "Number", j);
146 val2 = ipmi_control_get_num_light_transitions(control,
147 i, j);
148 ipmi_cmdlang_out_int(cmd_info, "Num Transitions", val2);
149 for (k=0; k<val2; k++) {
150 ipmi_cmdlang_out(cmd_info, "Transition", NULL);
151 ipmi_cmdlang_down(cmd_info);
152 ipmi_cmdlang_out_int(cmd_info, "Number", k);
153 val3 = ipmi_control_get_light_color(control, i, j, k);
154 ipmi_cmdlang_out(cmd_info, "Color",
155 ipmi_get_color_string(val3));
156 ipmi_cmdlang_out_int(cmd_info, "Time",
157 ipmi_control_get_light_color_time
158 (control, i, j, k));
159 ipmi_cmdlang_up(cmd_info);
160 }
161 ipmi_cmdlang_up(cmd_info);
162 }
163 ipmi_cmdlang_up(cmd_info);
164 }
165 }
166 break;
167
168 case IPMI_CONTROL_IDENTIFIER:
169 ipmi_cmdlang_out_int(cmd_info, "Max Length",
170 ipmi_control_identifier_get_max_length(control));
171 break;
172
173 case IPMI_CONTROL_DISPLAY:
174 break;
175
176 case IPMI_CONTROL_RELAY:
177 case IPMI_CONTROL_ALARM:
178 case IPMI_CONTROL_RESET:
179 case IPMI_CONTROL_POWER:
180 case IPMI_CONTROL_FAN_SPEED:
181 case IPMI_CONTROL_ONE_SHOT_RESET:
182 case IPMI_CONTROL_OUTPUT:
183 case IPMI_CONTROL_ONE_SHOT_OUTPUT:
184 break;
185 }
186 return;
187
188 out_err:
189 ipmi_control_get_name(control, cmdlang->objstr,
190 cmdlang->objstr_len);
191 cmdlang->location = "cmd_control.c(control_dump)";
192 }
193
194 static void
control_info(ipmi_control_t * control,void * cb_data)195 control_info(ipmi_control_t *control, void *cb_data)
196 {
197 ipmi_cmd_info_t *cmd_info = cb_data;
198 char control_name[IPMI_CONTROL_NAME_LEN];
199
200 ipmi_control_get_name(control, control_name, sizeof(control_name));
201
202 ipmi_cmdlang_out(cmd_info, "Control", NULL);
203 ipmi_cmdlang_down(cmd_info);
204 ipmi_cmdlang_out(cmd_info, "Name", control_name);
205 control_dump(control, cmd_info);
206 ipmi_cmdlang_up(cmd_info);
207 }
208
209 static void
control_set_done(ipmi_control_t * control,int err,void * cb_data)210 control_set_done(ipmi_control_t *control,
211 int err,
212 void *cb_data)
213 {
214 ipmi_cmd_info_t *cmd_info = cb_data;
215 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
216 char control_name[IPMI_CONTROL_NAME_LEN];
217
218 ipmi_cmdlang_lock(cmd_info);
219 if (err) {
220 cmdlang->errstr = "Error setting control";
221 cmdlang->err = err;
222 ipmi_control_get_name(control, cmdlang->objstr,
223 cmdlang->objstr_len);
224 cmdlang->location = "cmd_control.c(control_set_done)";
225 goto out;
226 }
227
228 ipmi_control_get_name(control, control_name, sizeof(control_name));
229 ipmi_cmdlang_out(cmd_info, "Set done", control_name);
230
231 out:
232 ipmi_cmdlang_unlock(cmd_info);
233 ipmi_cmdlang_cmd_info_put(cmd_info);
234 }
235
236 static void
control_set(ipmi_control_t * control,void * cb_data)237 control_set(ipmi_control_t *control, void *cb_data)
238 {
239 ipmi_cmd_info_t *cmd_info = cb_data;
240 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
241 int *data = NULL;
242 unsigned char *ucdata = NULL;
243 int num;
244 int i;
245 int rv;
246 int curr_arg = ipmi_cmdlang_get_curr_arg(cmd_info);
247 int argc = ipmi_cmdlang_get_argc(cmd_info);
248 char **argv = ipmi_cmdlang_get_argv(cmd_info);
249 ipmi_light_setting_t *s = NULL;
250
251
252 num = ipmi_control_get_num_vals(control);
253 if ((argc - curr_arg) < num) {
254 /* Not enough parameters */
255 cmdlang->errstr = "Not enough parameters";
256 cmdlang->err = EINVAL;
257 goto out_err;
258 }
259
260 switch (ipmi_control_get_type(control)) {
261 case IPMI_CONTROL_LIGHT:
262 if (!ipmi_control_light_set_with_setting(control))
263 goto normal_val_set;
264
265 s = ipmi_alloc_light_settings(num);
266 if (!s) {
267 cmdlang->errstr = "Out of memory";
268 cmdlang->err = ENOMEM;
269 goto out_err;
270 }
271
272 for (i=0; i<num; i++) {
273 int val;
274
275 if (strcmp(argv[curr_arg], "lc") == 0) {
276 ipmi_light_setting_set_local_control(s, i, 1);
277 continue;
278 } else if (strcmp(argv[curr_arg], "nolc") == 0) {
279 ipmi_light_setting_set_local_control(s, i, 0);
280 } else {
281 cmdlang->errstr = "Invalid local control setting";
282 cmdlang->err = EINVAL;
283 goto out_err;
284 }
285 curr_arg++;
286
287 ipmi_cmdlang_get_color(argv[curr_arg], &val, cmd_info);
288 if (cmdlang->err)
289 goto out_err;
290 rv = ipmi_light_setting_set_color(s, i, val);
291 if (rv) {
292 cmdlang->errstr = "Error setting color";
293 cmdlang->err = rv;
294 goto out_err;
295 }
296 curr_arg++;
297
298 ipmi_cmdlang_get_int(argv[curr_arg], &val, cmd_info);
299 if (cmdlang->err) {
300 cmdlang->errstr = "Invalid on time";
301 goto out_err;
302 }
303 rv = ipmi_light_setting_set_on_time(s, i, val);
304 if (rv) {
305 cmdlang->errstr = "Error setting on time";
306 cmdlang->err = rv;
307 goto out_err;
308 }
309 curr_arg++;
310
311 ipmi_cmdlang_get_int(argv[curr_arg], &val, cmd_info);
312 if (cmdlang->err) {
313 cmdlang->errstr = "Invalid off time";
314 goto out_err;
315 }
316 rv = ipmi_light_setting_set_off_time(s, i, val);
317 if (rv) {
318 cmdlang->errstr = "Error setting off time";
319 cmdlang->err = rv;
320 goto out_err;
321 }
322 curr_arg++;
323 }
324
325 ipmi_cmdlang_cmd_info_get(cmd_info);
326 rv = ipmi_control_set_light(control, s, control_set_done,
327 cmd_info);
328 if (rv) {
329 ipmi_cmdlang_cmd_info_put(cmd_info);
330 cmdlang->errstr = "Error setting light control";
331 cmdlang->err = rv;
332 goto out_err;
333 }
334 ipmi_free_light_settings(s);
335 break;
336
337 case IPMI_CONTROL_IDENTIFIER:
338 num = ipmi_control_identifier_get_max_length(control);
339 ucdata = ipmi_mem_alloc(num);
340 if (!ucdata) {
341 cmdlang->errstr = "Out of memory";
342 cmdlang->err = ENOMEM;
343 goto out_err;
344 }
345 for (i=0; i<num; i++) {
346 ipmi_cmdlang_get_uchar(argv[curr_arg], &ucdata[i], cmd_info);
347 if (cmdlang->err) {
348 cmdlang->errstr = "value invalid";
349 goto out_err;
350 }
351 curr_arg++;
352 }
353
354 ipmi_cmdlang_cmd_info_get(cmd_info);
355 rv = ipmi_control_identifier_set_val(control, ucdata, i,
356 control_set_done, cmd_info);
357 if (rv) {
358 ipmi_cmdlang_cmd_info_put(cmd_info);
359 cmdlang->errstr = "Error setting id control";
360 cmdlang->err = rv;
361 goto out_err;
362 }
363 ipmi_mem_free(ucdata);
364 break;
365
366 case IPMI_CONTROL_DISPLAY:
367 cmdlang->errstr = "Setting displays not currently supported";
368 cmdlang->err = ENOSYS;
369 goto out_err;
370 break;
371
372 case IPMI_CONTROL_RELAY:
373 case IPMI_CONTROL_ALARM:
374 case IPMI_CONTROL_RESET:
375 case IPMI_CONTROL_POWER:
376 case IPMI_CONTROL_FAN_SPEED:
377 case IPMI_CONTROL_ONE_SHOT_RESET:
378 case IPMI_CONTROL_OUTPUT:
379 case IPMI_CONTROL_ONE_SHOT_OUTPUT:
380 normal_val_set:
381 data = ipmi_mem_alloc(num * sizeof(int));
382 if (!data) {
383 cmdlang->errstr = "Out of memory";
384 cmdlang->err = ENOMEM;
385 goto out_err;
386 }
387 for (i=0; i<num; i++) {
388 ipmi_cmdlang_get_int(argv[curr_arg], &data[i], cmd_info);
389 if (cmdlang->err) {
390 cmdlang->errstr = "value invalid";
391 goto out_err;
392 }
393 curr_arg++;
394 }
395
396 ipmi_cmdlang_cmd_info_get(cmd_info);
397 rv = ipmi_control_set_val(control, data, control_set_done, cmd_info);
398 if (rv) {
399 ipmi_cmdlang_cmd_info_put(cmd_info);
400 cmdlang->errstr = "Error setting control";
401 cmdlang->err = rv;
402 goto out_err;
403 }
404 ipmi_mem_free(data);
405 break;
406 }
407 return;
408
409 out_err:
410 ipmi_control_get_name(control, cmdlang->objstr,
411 cmdlang->objstr_len);
412 cmdlang->location = "cmd_control.c(control_set)";
413 if (s)
414 ipmi_free_light_settings(s);
415 if (ucdata)
416 ipmi_mem_free(ucdata);
417 if (data)
418 ipmi_mem_free(data);
419 }
420
421 static void
control_get_light_done(ipmi_control_t * control,int err,ipmi_light_setting_t * s,void * cb_data)422 control_get_light_done(ipmi_control_t *control,
423 int err,
424 ipmi_light_setting_t *s,
425 void *cb_data)
426 {
427 ipmi_cmd_info_t *cmd_info = cb_data;
428 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
429 int i, num;
430 int rv;
431
432 ipmi_cmdlang_lock(cmd_info);
433 if (err) {
434 cmdlang->errstr = "Error setting control";
435 cmdlang->err = err;
436 goto out;
437 }
438
439 num = ipmi_light_setting_get_count(s);
440 for (i=0; i<num; i++) {
441 int val;
442
443 ipmi_cmdlang_out(cmd_info, "Light", NULL);
444 ipmi_cmdlang_down(cmd_info);
445 ipmi_cmdlang_out_int(cmd_info, "Num", i);
446 rv = ipmi_light_setting_in_local_control(s, i, &val);
447 if (rv) {
448 cmdlang->errstr = "Error getting if in local control";
449 cmdlang->err = rv;
450 goto out;
451 }
452 ipmi_cmdlang_out_bool(cmd_info, "Local Control", val);
453 if (!val) {
454 rv = ipmi_light_setting_get_color(s, i, &val);
455 if (rv) {
456 cmdlang->errstr = "Error getting color";
457 cmdlang->err = rv;
458 goto out;
459 }
460 ipmi_cmdlang_out(cmd_info, "Color", ipmi_get_color_string(val));
461
462 rv = ipmi_light_setting_get_on_time(s, i, &val);
463 if (rv) {
464 cmdlang->errstr = "Error getting on time";
465 cmdlang->err = rv;
466 goto out;
467 }
468 ipmi_cmdlang_out_int(cmd_info, "On Time", val);
469
470 rv = ipmi_light_setting_get_off_time(s, i, &val);
471 if (rv) {
472 cmdlang->errstr = "Error getting off time";
473 cmdlang->err = rv;
474 goto out;
475 }
476 ipmi_cmdlang_out_int(cmd_info, "Off Time", val);
477 }
478 ipmi_cmdlang_up(cmd_info);
479 }
480
481 out:
482 if (cmdlang->err) {
483 ipmi_control_get_name(control, cmdlang->objstr,
484 cmdlang->objstr_len);
485 cmdlang->location = "cmd_control.c(control_get_light_done)";
486 }
487 ipmi_cmdlang_unlock(cmd_info);
488 ipmi_cmdlang_cmd_info_put(cmd_info);
489 }
490
491 static void
control_get_id_done(ipmi_control_t * control,int err,unsigned char * val,int length,void * cb_data)492 control_get_id_done(ipmi_control_t *control,
493 int err,
494 unsigned char *val,
495 int length,
496 void *cb_data)
497 {
498 ipmi_cmd_info_t *cmd_info = cb_data;
499 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
500
501 ipmi_cmdlang_lock(cmd_info);
502 if (err) {
503 cmdlang->errstr = "Error setting control";
504 cmdlang->err = err;
505 goto out;
506 }
507
508 ipmi_cmdlang_out_binary(cmd_info, "Data", (char *) val, length);
509
510 out:
511 if (cmdlang->err) {
512 ipmi_control_get_name(control, cmdlang->objstr,
513 cmdlang->objstr_len);
514 cmdlang->location = "cmd_control.c(control_get_light_done)";
515 }
516 ipmi_cmdlang_unlock(cmd_info);
517 ipmi_cmdlang_cmd_info_put(cmd_info);
518 }
519
520 static void
control_get_done(ipmi_control_t * control,int err,int * val,void * cb_data)521 control_get_done(ipmi_control_t *control,
522 int err,
523 int *val,
524 void *cb_data)
525 {
526 ipmi_cmd_info_t *cmd_info = cb_data;
527 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
528 int i, num;
529 char control_name[IPMI_CONTROL_NAME_LEN];
530
531 ipmi_control_get_name(control, control_name, sizeof(control_name));
532
533 ipmi_cmdlang_lock(cmd_info);
534 if (err) {
535 cmdlang->errstr = "Error setting control";
536 cmdlang->err = err;
537 goto out;
538 }
539
540 ipmi_cmdlang_out(cmd_info, "Control", NULL);
541 ipmi_cmdlang_down(cmd_info);
542 ipmi_cmdlang_out(cmd_info, "Name", control_name);
543 num = ipmi_control_get_num_vals(control);
544 for (i=0; i<num; i++) {
545 ipmi_cmdlang_out(cmd_info, "Value", NULL);
546 ipmi_cmdlang_down(cmd_info);
547 ipmi_cmdlang_out_int(cmd_info, "Num", i);
548 ipmi_cmdlang_out_int(cmd_info, "Value", val[i]);
549 ipmi_cmdlang_up(cmd_info);
550 }
551 ipmi_cmdlang_up(cmd_info);
552
553 out:
554 if (cmdlang->err) {
555 ipmi_control_get_name(control, cmdlang->objstr,
556 cmdlang->objstr_len);
557 cmdlang->location = "cmd_control.c(control_get_light_done)";
558 }
559 ipmi_cmdlang_unlock(cmd_info);
560 ipmi_cmdlang_cmd_info_put(cmd_info);
561 }
562
563 static void
control_get(ipmi_control_t * control,void * cb_data)564 control_get(ipmi_control_t *control, void *cb_data)
565 {
566 ipmi_cmd_info_t *cmd_info = cb_data;
567 ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
568 int rv;
569
570
571 switch (ipmi_control_get_type(control)) {
572 case IPMI_CONTROL_LIGHT:
573 if (!ipmi_control_light_set_with_setting(control))
574 goto normal_val_get;
575
576 ipmi_cmdlang_cmd_info_get(cmd_info);
577 rv = ipmi_control_get_light(control, control_get_light_done, cmd_info);
578 if (rv) {
579 ipmi_cmdlang_cmd_info_put(cmd_info);
580 cmdlang->errstr = "Error getting light control";
581 cmdlang->err = rv;
582 goto out_err;
583 }
584 break;
585
586 case IPMI_CONTROL_IDENTIFIER:
587 ipmi_cmdlang_cmd_info_get(cmd_info);
588 rv = ipmi_control_identifier_get_val(control,
589 control_get_id_done, cmd_info);
590 if (rv) {
591 ipmi_cmdlang_cmd_info_put(cmd_info);
592 cmdlang->errstr = "Error getting id control";
593 cmdlang->err = rv;
594 goto out_err;
595 }
596 break;
597
598 case IPMI_CONTROL_DISPLAY:
599 cmdlang->errstr = "Getting displays not currently supported";
600 cmdlang->err = ENOSYS;
601 goto out_err;
602 break;
603
604 case IPMI_CONTROL_RELAY:
605 case IPMI_CONTROL_ALARM:
606 case IPMI_CONTROL_RESET:
607 case IPMI_CONTROL_POWER:
608 case IPMI_CONTROL_FAN_SPEED:
609 case IPMI_CONTROL_ONE_SHOT_RESET:
610 case IPMI_CONTROL_OUTPUT:
611 case IPMI_CONTROL_ONE_SHOT_OUTPUT:
612 normal_val_get:
613 ipmi_cmdlang_cmd_info_get(cmd_info);
614 rv = ipmi_control_get_val(control, control_get_done, cmd_info);
615 if (rv) {
616 ipmi_cmdlang_cmd_info_put(cmd_info);
617 cmdlang->errstr = "Error getting control";
618 cmdlang->err = rv;
619 goto out_err;
620 }
621 break;
622 }
623 return;
624
625 out_err:
626 ipmi_control_get_name(control, cmdlang->objstr,
627 cmdlang->objstr_len);
628 cmdlang->location = "cmd_control.c(control_get)";
629 }
630
631 static int
control_event_handler(ipmi_control_t * control,int * valid_vals,int * vals,void * cb_data,ipmi_event_t * event)632 control_event_handler(ipmi_control_t *control,
633 int *valid_vals,
634 int *vals,
635 void *cb_data,
636 ipmi_event_t *event)
637 {
638 ipmi_cmd_info_t *evi;
639 char control_name[IPMI_CONTROL_NAME_LEN];
640 int rv;
641 char *errstr;
642 int i;
643 int num;
644
645 ipmi_control_get_name(control, control_name, sizeof(control_name));
646
647 evi = ipmi_cmdlang_alloc_event_info();
648 if (!evi) {
649 rv = ENOMEM;
650 errstr = "Out of memory";
651 goto out_err;
652 }
653
654 ipmi_cmdlang_out(evi, "Object Type", "Control");
655 ipmi_cmdlang_out(evi, "Name", control_name);
656 ipmi_cmdlang_out(evi, "Operation", "Event");
657 num = ipmi_control_get_num_vals(control);
658 for (i=0; i<num; i++) {
659 if (!valid_vals[i])
660 continue;
661 ipmi_cmdlang_out(evi, "Value", NULL);
662 ipmi_cmdlang_down(evi);
663 ipmi_cmdlang_out_int(evi, "Number", i);
664 ipmi_cmdlang_out_int(evi, "Value", vals[i]);
665 ipmi_cmdlang_up(evi);
666 }
667 if (event) {
668 ipmi_cmdlang_out(evi, "Event", NULL);
669 ipmi_cmdlang_down(evi);
670 ipmi_cmdlang_event_out(event, evi);
671 ipmi_cmdlang_up(evi);
672 }
673 ipmi_cmdlang_cmd_info_put(evi);
674 return IPMI_EVENT_NOT_HANDLED;
675
676 out_err:
677 ipmi_cmdlang_global_err(control_name,
678 "cmd_control.c(ipmi_cmdlang_control_change)",
679 errstr, rv);
680 if (evi)
681 ipmi_cmdlang_cmd_info_put(evi);
682 return IPMI_EVENT_NOT_HANDLED;
683 }
684
685 void
ipmi_cmdlang_control_change(enum ipmi_update_e op,ipmi_entity_t * entity,ipmi_control_t * control,void * cb_data)686 ipmi_cmdlang_control_change(enum ipmi_update_e op,
687 ipmi_entity_t *entity,
688 ipmi_control_t *control,
689 void *cb_data)
690 {
691 char *errstr;
692 int rv;
693 ipmi_cmd_info_t *evi;
694 char control_name[IPMI_CONTROL_NAME_LEN];
695
696 ipmi_control_get_name(control, control_name, sizeof(control_name));
697
698 evi = ipmi_cmdlang_alloc_event_info();
699 if (!evi) {
700 rv = ENOMEM;
701 errstr = "Out of memory";
702 goto out_err;
703 }
704
705 ipmi_cmdlang_out(evi, "Object Type", "Control");
706 ipmi_cmdlang_out(evi, "Name", control_name);
707
708 switch (op) {
709 case IPMI_ADDED:
710 ipmi_cmdlang_out(evi, "Operation", "Add");
711 if (ipmi_cmdlang_get_evinfo())
712 control_dump(control, evi);
713
714 if (ipmi_control_has_events(control)) {
715 rv = ipmi_control_add_val_event_handler(control,
716 control_event_handler,
717 NULL);
718 if (rv) {
719 ipmi_cmdlang_global_err
720 (control_name,
721 "cmd_control.c(ipmi_cmdlang_control_change)",
722 "Unable to set event handler for control",
723 rv);
724 }
725 }
726 break;
727
728 case IPMI_DELETED:
729 ipmi_cmdlang_out(evi, "Operation", "Delete");
730 break;
731
732 case IPMI_CHANGED:
733 ipmi_cmdlang_out(evi, "Operation", "Change");
734 if (ipmi_cmdlang_get_evinfo())
735 control_dump(control, evi);
736 break;
737 }
738
739 ipmi_cmdlang_cmd_info_put(evi);
740 return;
741
742 out_err:
743 ipmi_cmdlang_global_err(control_name,
744 "cmd_control.c(ipmi_cmdlang_control_change)",
745 errstr, rv);
746 if (evi)
747 ipmi_cmdlang_cmd_info_put(evi);
748 }
749
750 static ipmi_cmdlang_cmd_t *control_cmds;
751
752 static ipmi_cmdlang_init_t cmds_control[] =
753 {
754 { "control", NULL,
755 "- Commands dealing with controls",
756 NULL, NULL, &control_cmds },
757 { "list", &control_cmds,
758 "- List all the entities in the system",
759 ipmi_cmdlang_entity_handler, control_list, NULL },
760 { "info", &control_cmds,
761 "<control> - Dump information about an control",
762 ipmi_cmdlang_control_handler, control_info, NULL },
763 { "set", &control_cmds,
764 "<control> <values> - Set the value of a control. The settings"
765 " depend on control type, most take one or more integer values. "
766 " An identifier type takes one or more unsigned characters. A"
767 " light set with settings take the form 'lc|nolc <color> <on time>"
768 " <off time>. lc and nolc turn on or of local control, the over"
769 " values should be obvious.",
770 ipmi_cmdlang_control_handler, control_set, NULL },
771 { "get", &control_cmds,
772 "<control> - Get the value of a control",
773 ipmi_cmdlang_control_handler, control_get, NULL },
774 };
775 #define CMDS_CONTROL_LEN (sizeof(cmds_control)/sizeof(ipmi_cmdlang_init_t))
776
777 int
ipmi_cmdlang_control_init(os_handler_t * os_hnd)778 ipmi_cmdlang_control_init(os_handler_t *os_hnd)
779 {
780 return ipmi_cmdlang_reg_table(cmds_control, CMDS_CONTROL_LEN);
781 }
782