4
* A command interpreter for OpenIPMI
6
* Author: MontaVista Software, Inc.
7
* Corey Minyard <minyard@mvista.com>
10
* Copyright 2004 MontaVista Software Inc.
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.
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.
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.
39
#include <OpenIPMI/ipmiif.h>
40
#include <OpenIPMI/ipmi_cmdlang.h>
42
/* Internal includes, do not use in your programs */
43
#include <OpenIPMI/internal/ipmi_malloc.h>
46
control_list_handler(ipmi_entity_t *entity, ipmi_control_t *control,
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];
56
ipmi_control_get_name(control, control_name, sizeof(control_name));
58
ipmi_cmdlang_out(cmd_info, "Name", control_name);
62
control_list(ipmi_entity_t *entity, void *cb_data)
64
ipmi_cmd_info_t *cmd_info = cb_data;
65
char entity_name[IPMI_ENTITY_NAME_LEN];
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);
79
control_dump(ipmi_control_t *control, ipmi_cmd_info_t *cmd_info)
81
ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
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);
99
str = ipmi_mem_alloc(len);
101
cmdlang->err = ENOMEM;
102
cmdlang->errstr = "Out of memory";
105
len = ipmi_control_get_id(control, str, len);
106
ipmi_cmdlang_out_type(cmd_info, "Id",
107
ipmi_control_get_id_type(control),
112
switch (ipmi_control_get_type(control)) {
113
case IPMI_CONTROL_LIGHT:
114
val = ipmi_control_light_set_with_setting(control);
116
ipmi_cmdlang_out(cmd_info, "Set with", "settings");
117
val = ipmi_control_light_has_local_control(control);
118
ipmi_cmdlang_out_bool(cmd_info, "Local Control", val);
119
for (i=IPMI_CONTROL_COLOR_BLACK; i<IPMI_CONTROL_COLOR_ORANGE; i++){
120
val = ipmi_control_light_is_color_supported(control, i);
122
ipmi_cmdlang_out(cmd_info, "Color",
123
ipmi_get_color_string(i));
126
ipmi_cmdlang_out(cmd_info, "Set with", "transitions");
127
for (i=0; i<num; i++) {
128
ipmi_cmdlang_out(cmd_info, "Light", NULL);
129
ipmi_cmdlang_down(cmd_info);
130
ipmi_cmdlang_out_int(cmd_info, "Number", i);
131
val = ipmi_control_get_num_light_values(control, i);
132
ipmi_cmdlang_out_int(cmd_info, "Num Values", val);
133
for (j=0; j<val; j++) {
134
ipmi_cmdlang_out(cmd_info, "Value", NULL);
135
ipmi_cmdlang_down(cmd_info);
136
ipmi_cmdlang_out_int(cmd_info, "Number", j);
137
val2 = ipmi_control_get_num_light_transitions(control,
139
ipmi_cmdlang_out_int(cmd_info, "Num Transitions", val2);
140
for (k=0; k<val2; k++) {
141
ipmi_cmdlang_out(cmd_info, "Transition", NULL);
142
ipmi_cmdlang_down(cmd_info);
143
ipmi_cmdlang_out_int(cmd_info, "Number", k);
144
val3 = ipmi_control_get_light_color(control, i, j, k);
145
ipmi_cmdlang_out(cmd_info, "Color",
146
ipmi_get_color_string(val3));
147
ipmi_cmdlang_out_int(cmd_info, "Time",
148
ipmi_control_get_light_color_time
150
ipmi_cmdlang_up(cmd_info);
152
ipmi_cmdlang_up(cmd_info);
154
ipmi_cmdlang_up(cmd_info);
159
case IPMI_CONTROL_IDENTIFIER:
160
ipmi_cmdlang_out_int(cmd_info, "Max Length",
161
ipmi_control_identifier_get_max_length(control));
164
case IPMI_CONTROL_DISPLAY:
167
case IPMI_CONTROL_RELAY:
168
case IPMI_CONTROL_ALARM:
169
case IPMI_CONTROL_RESET:
170
case IPMI_CONTROL_POWER:
171
case IPMI_CONTROL_FAN_SPEED:
172
case IPMI_CONTROL_ONE_SHOT_RESET:
173
case IPMI_CONTROL_OUTPUT:
174
case IPMI_CONTROL_ONE_SHOT_OUTPUT:
180
ipmi_control_get_name(control, cmdlang->objstr,
181
cmdlang->objstr_len);
182
cmdlang->location = "cmd_control.c(control_dump)";
186
control_info(ipmi_control_t *control, void *cb_data)
188
ipmi_cmd_info_t *cmd_info = cb_data;
189
char control_name[IPMI_CONTROL_NAME_LEN];
191
ipmi_control_get_name(control, control_name, sizeof(control_name));
193
ipmi_cmdlang_out(cmd_info, "Control", NULL);
194
ipmi_cmdlang_down(cmd_info);
195
ipmi_cmdlang_out(cmd_info, "Name", control_name);
196
control_dump(control, cmd_info);
197
ipmi_cmdlang_up(cmd_info);
201
control_set_done(ipmi_control_t *control,
205
ipmi_cmd_info_t *cmd_info = cb_data;
206
ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
207
char control_name[IPMI_CONTROL_NAME_LEN];
209
ipmi_cmdlang_lock(cmd_info);
211
cmdlang->errstr = "Error setting control";
213
ipmi_control_get_name(control, cmdlang->objstr,
214
cmdlang->objstr_len);
215
cmdlang->location = "cmd_control.c(control_set_done)";
219
ipmi_control_get_name(control, control_name, sizeof(control_name));
220
ipmi_cmdlang_out(cmd_info, "Set done", control_name);
223
ipmi_cmdlang_unlock(cmd_info);
224
ipmi_cmdlang_cmd_info_put(cmd_info);
228
control_set(ipmi_control_t *control, void *cb_data)
230
ipmi_cmd_info_t *cmd_info = cb_data;
231
ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
233
unsigned char *ucdata = NULL;
237
int curr_arg = ipmi_cmdlang_get_curr_arg(cmd_info);
238
int argc = ipmi_cmdlang_get_argc(cmd_info);
239
char **argv = ipmi_cmdlang_get_argv(cmd_info);
240
ipmi_light_setting_t *s = NULL;
243
num = ipmi_control_get_num_vals(control);
244
if ((argc - curr_arg) < num) {
245
/* Not enough parameters */
246
cmdlang->errstr = "Not enough parameters";
247
cmdlang->err = EINVAL;
251
switch (ipmi_control_get_type(control)) {
252
case IPMI_CONTROL_LIGHT:
253
if (!ipmi_control_light_set_with_setting(control))
256
s = ipmi_alloc_light_settings(num);
258
cmdlang->errstr = "Out of memory";
259
cmdlang->err = ENOMEM;
263
for (i=0; i<num; i++) {
266
if (strcmp(argv[curr_arg], "lc") == 0) {
267
ipmi_light_setting_set_local_control(s, i, 1);
269
} else if (strcmp(argv[curr_arg], "nolc") == 0) {
270
ipmi_light_setting_set_local_control(s, i, 0);
272
cmdlang->errstr = "Invalid local control setting";
273
cmdlang->err = EINVAL;
278
ipmi_cmdlang_get_color(argv[curr_arg], &val, cmd_info);
281
rv = ipmi_light_setting_set_color(s, i, val);
283
cmdlang->errstr = "Error setting color";
289
ipmi_cmdlang_get_int(argv[curr_arg], &val, cmd_info);
291
cmdlang->errstr = "Invalid on time";
294
rv = ipmi_light_setting_set_on_time(s, i, val);
296
cmdlang->errstr = "Error setting on time";
302
ipmi_cmdlang_get_int(argv[curr_arg], &val, cmd_info);
304
cmdlang->errstr = "Invalid off time";
307
rv = ipmi_light_setting_set_off_time(s, i, val);
309
cmdlang->errstr = "Error setting off time";
316
ipmi_cmdlang_cmd_info_get(cmd_info);
317
rv = ipmi_control_set_light(control, s, control_set_done,
320
ipmi_cmdlang_cmd_info_put(cmd_info);
321
cmdlang->errstr = "Error setting light control";
325
ipmi_free_light_settings(s);
328
case IPMI_CONTROL_IDENTIFIER:
329
num = ipmi_control_identifier_get_max_length(control);
330
ucdata = ipmi_mem_alloc(num);
332
cmdlang->errstr = "Out of memory";
333
cmdlang->err = ENOMEM;
336
for (i=0; i<num; i++) {
337
ipmi_cmdlang_get_uchar(argv[curr_arg], &ucdata[i], cmd_info);
339
cmdlang->errstr = "value invalid";
345
ipmi_cmdlang_cmd_info_get(cmd_info);
346
rv = ipmi_control_identifier_set_val(control, ucdata, i,
347
control_set_done, cmd_info);
349
ipmi_cmdlang_cmd_info_put(cmd_info);
350
cmdlang->errstr = "Error setting id control";
354
ipmi_mem_free(ucdata);
357
case IPMI_CONTROL_DISPLAY:
358
cmdlang->errstr = "Setting displays not currently supported";
359
cmdlang->err = ENOSYS;
363
case IPMI_CONTROL_RELAY:
364
case IPMI_CONTROL_ALARM:
365
case IPMI_CONTROL_RESET:
366
case IPMI_CONTROL_POWER:
367
case IPMI_CONTROL_FAN_SPEED:
368
case IPMI_CONTROL_ONE_SHOT_RESET:
369
case IPMI_CONTROL_OUTPUT:
370
case IPMI_CONTROL_ONE_SHOT_OUTPUT:
372
data = ipmi_mem_alloc(num * sizeof(int));
374
cmdlang->errstr = "Out of memory";
375
cmdlang->err = ENOMEM;
378
for (i=0; i<num; i++) {
379
ipmi_cmdlang_get_int(argv[curr_arg], &data[i], cmd_info);
381
cmdlang->errstr = "value invalid";
387
ipmi_cmdlang_cmd_info_get(cmd_info);
388
rv = ipmi_control_set_val(control, data, control_set_done, cmd_info);
390
ipmi_cmdlang_cmd_info_put(cmd_info);
391
cmdlang->errstr = "Error setting control";
401
ipmi_control_get_name(control, cmdlang->objstr,
402
cmdlang->objstr_len);
403
cmdlang->location = "cmd_control.c(control_set)";
405
ipmi_free_light_settings(s);
407
ipmi_mem_free(ucdata);
413
control_get_light_done(ipmi_control_t *control,
415
ipmi_light_setting_t *s,
418
ipmi_cmd_info_t *cmd_info = cb_data;
419
ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
423
ipmi_cmdlang_lock(cmd_info);
425
cmdlang->errstr = "Error setting control";
430
num = ipmi_light_setting_get_count(s);
431
for (i=0; i<num; i++) {
434
ipmi_cmdlang_out(cmd_info, "Light", NULL);
435
ipmi_cmdlang_down(cmd_info);
436
ipmi_cmdlang_out_int(cmd_info, "Num", i);
437
rv = ipmi_light_setting_in_local_control(s, i, &val);
439
cmdlang->errstr = "Error getting if in local control";
443
ipmi_cmdlang_out_bool(cmd_info, "Local Control", val);
445
rv = ipmi_light_setting_get_color(s, i, &val);
447
cmdlang->errstr = "Error getting color";
451
ipmi_cmdlang_out(cmd_info, "Color", ipmi_get_color_string(val));
453
rv = ipmi_light_setting_get_on_time(s, i, &val);
455
cmdlang->errstr = "Error getting on time";
459
ipmi_cmdlang_out_int(cmd_info, "On Time", val);
461
rv = ipmi_light_setting_get_off_time(s, i, &val);
463
cmdlang->errstr = "Error getting off time";
467
ipmi_cmdlang_out_int(cmd_info, "Off Time", val);
469
ipmi_cmdlang_up(cmd_info);
474
ipmi_control_get_name(control, cmdlang->objstr,
475
cmdlang->objstr_len);
476
cmdlang->location = "cmd_control.c(control_get_light_done)";
478
ipmi_cmdlang_unlock(cmd_info);
479
ipmi_cmdlang_cmd_info_put(cmd_info);
483
control_get_id_done(ipmi_control_t *control,
489
ipmi_cmd_info_t *cmd_info = cb_data;
490
ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
492
ipmi_cmdlang_lock(cmd_info);
494
cmdlang->errstr = "Error setting control";
499
ipmi_cmdlang_out_binary(cmd_info, "Data", val, length);
503
ipmi_control_get_name(control, cmdlang->objstr,
504
cmdlang->objstr_len);
505
cmdlang->location = "cmd_control.c(control_get_light_done)";
507
ipmi_cmdlang_unlock(cmd_info);
508
ipmi_cmdlang_cmd_info_put(cmd_info);
512
control_get_done(ipmi_control_t *control,
517
ipmi_cmd_info_t *cmd_info = cb_data;
518
ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
520
char control_name[IPMI_CONTROL_NAME_LEN];
522
ipmi_control_get_name(control, control_name, sizeof(control_name));
524
ipmi_cmdlang_lock(cmd_info);
526
cmdlang->errstr = "Error setting control";
531
ipmi_cmdlang_out(cmd_info, "Control", NULL);
532
ipmi_cmdlang_down(cmd_info);
533
ipmi_cmdlang_out(cmd_info, "Name", control_name);
534
num = ipmi_control_get_num_vals(control);
535
for (i=0; i<num; i++) {
536
ipmi_cmdlang_out(cmd_info, "Value", NULL);
537
ipmi_cmdlang_down(cmd_info);
538
ipmi_cmdlang_out_int(cmd_info, "Num", i);
539
ipmi_cmdlang_out_int(cmd_info, "Value", val[i]);
540
ipmi_cmdlang_up(cmd_info);
542
ipmi_cmdlang_up(cmd_info);
546
ipmi_control_get_name(control, cmdlang->objstr,
547
cmdlang->objstr_len);
548
cmdlang->location = "cmd_control.c(control_get_light_done)";
550
ipmi_cmdlang_unlock(cmd_info);
551
ipmi_cmdlang_cmd_info_put(cmd_info);
555
control_get(ipmi_control_t *control, void *cb_data)
557
ipmi_cmd_info_t *cmd_info = cb_data;
558
ipmi_cmdlang_t *cmdlang = ipmi_cmdinfo_get_cmdlang(cmd_info);
562
switch (ipmi_control_get_type(control)) {
563
case IPMI_CONTROL_LIGHT:
564
if (!ipmi_control_light_set_with_setting(control))
567
ipmi_cmdlang_cmd_info_get(cmd_info);
568
rv = ipmi_control_get_light(control, control_get_light_done, cmd_info);
570
ipmi_cmdlang_cmd_info_put(cmd_info);
571
cmdlang->errstr = "Error getting light control";
577
case IPMI_CONTROL_IDENTIFIER:
578
ipmi_cmdlang_cmd_info_get(cmd_info);
579
rv = ipmi_control_identifier_get_val(control,
580
control_get_id_done, cmd_info);
582
ipmi_cmdlang_cmd_info_put(cmd_info);
583
cmdlang->errstr = "Error getting id control";
589
case IPMI_CONTROL_DISPLAY:
590
cmdlang->errstr = "Getting displays not currently supported";
591
cmdlang->err = ENOSYS;
595
case IPMI_CONTROL_RELAY:
596
case IPMI_CONTROL_ALARM:
597
case IPMI_CONTROL_RESET:
598
case IPMI_CONTROL_POWER:
599
case IPMI_CONTROL_FAN_SPEED:
600
case IPMI_CONTROL_ONE_SHOT_RESET:
601
case IPMI_CONTROL_OUTPUT:
602
case IPMI_CONTROL_ONE_SHOT_OUTPUT:
604
ipmi_cmdlang_cmd_info_get(cmd_info);
605
rv = ipmi_control_get_val(control, control_get_done, cmd_info);
607
ipmi_cmdlang_cmd_info_put(cmd_info);
608
cmdlang->errstr = "Error getting control";
617
ipmi_control_get_name(control, cmdlang->objstr,
618
cmdlang->objstr_len);
619
cmdlang->location = "cmd_control.c(control_get)";
623
control_event_handler(ipmi_control_t *control,
629
ipmi_cmd_info_t *evi;
630
char control_name[IPMI_CONTROL_NAME_LEN];
636
ipmi_control_get_name(control, control_name, sizeof(control_name));
638
evi = ipmi_cmdlang_alloc_event_info();
641
errstr = "Out of memory";
645
ipmi_cmdlang_out(evi, "Object Type", "Control");
646
ipmi_cmdlang_out(evi, "Name", control_name);
647
ipmi_cmdlang_out(evi, "Operation", "Event");
648
num = ipmi_control_get_num_vals(control);
649
for (i=0; i<num; i++) {
652
ipmi_cmdlang_out(evi, "Value", NULL);
653
ipmi_cmdlang_down(evi);
654
ipmi_cmdlang_out_int(evi, "Number", i);
655
ipmi_cmdlang_out_int(evi, "Value", vals[i]);
656
ipmi_cmdlang_up(evi);
659
ipmi_cmdlang_out(evi, "Event", NULL);
660
ipmi_cmdlang_down(evi);
661
ipmi_cmdlang_event_out(event, evi);
662
ipmi_cmdlang_up(evi);
664
ipmi_cmdlang_cmd_info_put(evi);
665
return IPMI_EVENT_HANDLED;
668
ipmi_cmdlang_global_err(control_name,
669
"cmd_control.c(ipmi_cmdlang_control_change)",
672
ipmi_cmdlang_cmd_info_put(evi);
673
return IPMI_EVENT_NOT_HANDLED;
677
ipmi_cmdlang_control_change(enum ipmi_update_e op,
678
ipmi_entity_t *entity,
679
ipmi_control_t *control,
684
ipmi_cmd_info_t *evi;
685
char control_name[IPMI_CONTROL_NAME_LEN];
687
ipmi_control_get_name(control, control_name, sizeof(control_name));
689
evi = ipmi_cmdlang_alloc_event_info();
692
errstr = "Out of memory";
696
ipmi_cmdlang_out(evi, "Object Type", "Control");
697
ipmi_cmdlang_out(evi, "Name", control_name);
701
ipmi_cmdlang_out(evi, "Operation", "Add");
702
if (ipmi_cmdlang_get_evinfo())
703
control_dump(control, evi);
705
if (ipmi_control_has_events(control)) {
706
rv = ipmi_control_add_val_event_handler(control,
707
control_event_handler,
710
ipmi_cmdlang_global_err
712
"cmd_control.c(ipmi_cmdlang_control_change)",
713
"Unable to set event handler for control",
720
ipmi_cmdlang_out(evi, "Operation", "Delete");
724
ipmi_cmdlang_out(evi, "Operation", "Change");
725
if (ipmi_cmdlang_get_evinfo())
726
control_dump(control, evi);
730
ipmi_cmdlang_cmd_info_put(evi);
734
ipmi_cmdlang_global_err(control_name,
735
"cmd_control.c(ipmi_cmdlang_control_change)",
738
ipmi_cmdlang_cmd_info_put(evi);
741
static ipmi_cmdlang_cmd_t *control_cmds;
743
static ipmi_cmdlang_init_t cmds_control[] =
746
"- Commands dealing with controls",
747
NULL, NULL, &control_cmds },
748
{ "list", &control_cmds,
749
"- List all the entities in the system",
750
ipmi_cmdlang_entity_handler, control_list, NULL },
751
{ "info", &control_cmds,
752
"<control> - Dump information about an control",
753
ipmi_cmdlang_control_handler, control_info, NULL },
754
{ "set", &control_cmds,
755
"<control> <values> - Set the value of a control. The settings"
756
" depend on control type, most take one or more integer values. "
757
" An identifier type takes one or more unsigned characters. A"
758
" light set with settings take the form 'lc|nolc <color> <on time>"
759
" <off time>. lc and nolc turn on or of local control, the over"
760
" values should be obvious.",
761
ipmi_cmdlang_control_handler, control_set, NULL },
762
{ "get", &control_cmds,
763
"<control> - Get the value of a control",
764
ipmi_cmdlang_control_handler, control_get, NULL },
766
#define CMDS_CONTROL_LEN (sizeof(cmds_control)/sizeof(ipmi_cmdlang_init_t))
769
ipmi_cmdlang_control_init(os_handler_t *os_hnd)
771
return ipmi_cmdlang_reg_table(cmds_control, CMDS_CONTROL_LEN);