ebe5ae8b3f52255230bd63f8d9d5308f686fbaf2
[platform/upstream/gt.git] / source / gadget / src / gadget.c
1 /*
2  * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <strings.h>
21 #include <unistd.h>
22 #include <getopt.h>
23 #include <errno.h>
24
25 #include "gadget.h"
26 #include "common.h"
27 #include "parser.h"
28 #include "backend.h"
29
30 #define GET_EXECUTABLE(func) \
31         (backend_ctx.backend->gadget->func ? \
32          backend_ctx.backend->gadget->func : \
33          gt_gadget_backend_not_implemented.func)
34
35 const struct gt_gadget_str gadget_strs[] = {
36         { "product", usbg_set_gadget_product },
37         { "manufacturer", usbg_set_gadget_manufacturer },
38         { "serialnumber", usbg_set_gadget_serial_number },
39 };
40
41 static void gt_gadget_create_destructor(void *data)
42 {
43         struct gt_gadget_create_data *dt;
44         int i;
45
46         if (data == NULL)
47                 return;
48         dt = (struct gt_gadget_create_data *)data;
49         for (i = 0; i < GT_GADGET_STRS_COUNT; i++)
50                 free(dt->str_val[i]);
51
52         free(dt);
53 }
54
55 char *attr_type_get(usbg_gadget_attr a)
56 {
57         switch (a) {
58         case B_DEVICE_CLASS:
59         case B_DEVICE_SUB_CLASS:
60         case B_DEVICE_PROTOCOL:
61         case B_MAX_PACKET_SIZE_0:
62                 return "y";
63
64         case BCD_USB:
65         case ID_VENDOR:
66         case ID_PRODUCT:
67         case BCD_DEVICE:
68                 return "q";
69
70         default:
71                 return NULL;
72         }
73 }
74
75 static int attr_val_in_range(usbg_gadget_attr a, unsigned long int val)
76 {
77         char *type = attr_type_get(a);
78
79         if (!type)
80                 return 0;
81
82         if (type[0] == 'y')
83                 return val <= UINT8_MAX;
84         else if (type[0] == 'q')
85                 return val <= UINT16_MAX;
86         else
87                 return 0;
88 }
89
90 static int gt_gadget_create_help(void *data)
91 {
92         int i;
93
94         printf("usage: %s create <name> [attr=value]...\n"
95                "Create new gadget of specified name, attributes and language strings.\n"
96                "\n"
97                "Attributes:\n",
98                program_name);
99
100         for (i = USBG_GADGET_ATTR_MIN; i < USBG_GADGET_ATTR_MAX; i++)
101                 printf("  %s\n", usbg_get_gadget_attr_str(i));
102
103         printf("Device strings (en_US locale):\n");
104
105         for (i = 0; i < GT_GADGET_STRS_COUNT; i++)
106                 printf("  %s\n", gadget_strs[i].name);
107
108         return 0;
109 }
110
111 static void gt_parse_gadget_create(const Command *cmd, int argc, char **argv,
112                 ExecutableCommand *exec, void *data)
113 {
114         struct gt_gadget_create_data *dt;
115         int ind;
116         int c;
117         int avaible_opts = GT_FORCE | GT_HELP;
118         struct gt_setting *setting, *attrs = NULL;
119         _Bool iter;
120         int i;
121
122         dt = zalloc(sizeof(*dt));
123         if (dt == NULL)
124                 goto out;
125
126         ind = gt_get_options(&dt->opts, avaible_opts, argc, argv);
127         if (ind < 0 || dt->opts & GT_HELP)
128                 goto out;
129
130         if (ind == argc)
131                 goto out;
132
133         dt->name = argv[ind++];
134
135         c = gt_parse_setting_list(&attrs, argc - ind, argv + ind);
136         if (c < 0)
137                 goto out;
138
139         for (i = 0; i < USBG_GADGET_ATTR_MAX; i++)
140                 dt->attr_val[i] = -1;
141         memset(dt->str_val, 0, sizeof(dt->str_val));
142
143         for (setting = attrs; setting->variable; setting++) {
144                 int attr_id;
145
146                 iter = TRUE;
147
148                 attr_id = usbg_lookup_gadget_attr(setting->variable);
149                 if (attr_id >= 0) {
150                         unsigned long int val;
151                         char *endptr = NULL;
152
153                         errno = 0;
154                         val = strtoul(setting->value, &endptr, 0);
155                         if (errno
156                             || *setting->value == 0
157                             || (endptr && *endptr != 0)
158                             || attr_val_in_range(attr_id, val) == 0) {
159
160                                 fprintf(stderr, "Invalid value '%s' for attribute '%s'\n",
161                                         setting->value, setting->variable);
162                                 goto out;
163                         }
164
165                         dt->attr_val[attr_id] = val;
166                         iter = FALSE;
167                 }
168
169                 for (i = 0; iter && i < GT_GADGET_STRS_COUNT; i++) {
170                         if (streq(setting->variable, gadget_strs[i].name)) {
171                                 dt->str_val[i] = setting->value;
172                                 iter = FALSE;
173                                 break;
174                         }
175                 }
176
177                 if (iter) {
178                         fprintf(stderr, "Unknown attribute passed: %s\n", setting->variable);
179                         goto out;
180                 }
181         }
182
183         executable_command_set(exec, GET_EXECUTABLE(create),
184                                 (void *)dt, gt_gadget_create_destructor);
185
186         return;
187 out:
188         gt_setting_list_cleanup(attrs);
189         gt_gadget_create_destructor((void *)dt);
190         executable_command_set(exec, cmd->printHelp, data, NULL);
191 }
192
193 static int gt_gadget_rm_help(void *data)
194 {
195         printf("usage: %s rm [options] <name> \n"
196                "Remove gadget of specified name\n"
197                "\n"
198                "Options:\n"
199                "  -f, --force\tDisable gadget if it was enabled\n"
200                "  -r, --recursive\tRemove configs and functions recursively\n"
201                "  -h, --help\tPrint this help\n",
202                program_name);
203         return -1;
204 }
205
206 static void gt_parse_gadget_rm(const Command *cmd, int argc, char **argv,
207                 ExecutableCommand *exec, void *data)
208 {
209         struct gt_gadget_rm_data *dt;
210         int ind;
211         int avaible_opts = GT_FORCE | GT_RECURSIVE | GT_HELP;
212
213         dt = zalloc(sizeof(*dt));
214         if (dt == NULL)
215                 goto out;
216
217         ind = gt_get_options(&dt->opts, avaible_opts, argc, argv);
218         if (ind < 0 || dt->opts & GT_HELP)
219                 goto out;
220
221         if (argc - ind != 1)
222                 goto out;
223         dt->name = argv[ind];
224         executable_command_set(exec, GET_EXECUTABLE(rm), (void *)dt,
225                         free);
226         return;
227 out:
228         free(dt);
229         executable_command_set(exec, cmd->printHelp, data, NULL);
230 }
231
232 static void gt_gadget_get_destructor(void *data)
233 {
234         struct gt_gadget_get_data *dt;
235
236         if (data == NULL)
237                 return;
238         dt = (struct gt_gadget_get_data *)data;
239
240         free(dt->attrs);
241         free(dt);
242 }
243
244 static int gt_gadget_get_help(void *data)
245 {
246         printf("Gadget get help.\n");
247         return -1;
248 }
249
250 static void gt_parse_gadget_get(const Command *cmd, int argc, char **argv,
251                 ExecutableCommand *exec, void * data)
252 {
253         struct gt_gadget_get_data *dt = NULL;
254         int i;
255         int ind;
256         int avaible_opts = GT_HELP;
257
258         if (argc == 0)
259                 goto out;
260
261         dt = zalloc(sizeof(*dt));
262         if (dt == NULL)
263                 goto out;
264
265         ind = gt_get_options(&dt->opts, avaible_opts, argc, argv);
266         if (ind < 0 || dt->opts & GT_HELP)
267                 goto out;
268
269         dt->name = argv[ind++];
270         dt->attrs = calloc(argc - ind + 1, sizeof(char *));
271         if (dt->attrs == NULL)
272                 goto out;
273
274         i = 0;
275         while (argv[ind])
276                 dt->attrs[i++] = argv[ind++];
277
278         executable_command_set(exec, GET_EXECUTABLE(get), (void *)dt,
279                         gt_gadget_get_destructor);
280
281         return;
282 out:
283         gt_gadget_get_destructor((void *)dt);
284         executable_command_set(exec, cmd->printHelp, data, NULL);
285 }
286
287 static void gt_gadget_set_destructor(void *data)
288 {
289         struct gt_gadget_set_data *dt;
290
291         if (data == NULL)
292                 return;
293         dt = (struct gt_gadget_set_data *)data;
294         gt_setting_list_cleanup(dt->attrs);
295         free(dt);
296 }
297
298 static int gt_gadget_set_help(void *data)
299 {
300         printf("Gadget set help.\n");
301         return -1;
302 }
303
304 static void gt_parse_gadget_set(const Command *cmd, int argc, char **argv,
305                 ExecutableCommand *exec, void * data)
306 {
307         struct gt_gadget_set_data *dt = NULL;
308         int tmp;
309         int ind;
310         int avaible_opts = GT_HELP;
311
312         dt = zalloc(sizeof(*dt));
313         if (dt == NULL)
314                 goto out;
315
316         ind = gt_get_options(&dt->opts, avaible_opts, argc, argv);
317         if (ind < 0 || dt->opts & GT_HELP)
318                 goto out;
319
320         if (argc - ind < 2)
321                 goto out;
322
323         dt->name = argv[ind++];
324         tmp = gt_parse_setting_list(&dt->attrs, argc - ind, argv + ind);
325         if (tmp < 0)
326                 goto out;
327
328         executable_command_set(exec, GET_EXECUTABLE(set), (void *)dt,
329                         gt_gadget_set_destructor);
330         return;
331 out:
332         gt_gadget_set_destructor((void *)dt);
333         executable_command_set(exec, cmd->printHelp, data, NULL);
334 }
335
336 static int gt_gadget_enable_help(void *data)
337 {
338         printf("Gadget enable help.\n");
339         return -1;
340 }
341
342 static void gt_parse_gadget_enable(const Command *cmd, int argc,
343                 char **argv, ExecutableCommand *exec, void * data)
344 {
345         struct gt_gadget_enable_data *dt;
346         int ind;
347         int avaible_opts = GT_HELP;
348
349         dt = zalloc(sizeof(*dt));
350         if (dt == NULL)
351                 goto out;
352
353         ind = gt_get_options(&dt->opts, avaible_opts, argc, argv);
354         if (ind < 0 || dt->opts & GT_HELP)
355                 goto out;
356
357         switch (argc - ind) {
358         case 1:
359                 dt->gadget = argv[ind++];
360                 break;
361         case 2:
362                 dt->gadget = argv[ind++];
363                 dt->udc = argv[ind++];
364                 break;
365         default:
366                 goto out;
367         }
368
369         executable_command_set(exec, GET_EXECUTABLE(enable),
370                                 (void *)dt, free);
371         return;
372 out:
373         free((void *)dt);
374         executable_command_set(exec, cmd->printHelp, data, NULL);
375 }
376
377 static int gt_gadget_disable_help(void *data)
378 {
379         printf("Gadget disable help.\n");
380         return -1;
381 }
382
383 static void gt_parse_gadget_disable(const Command *cmd, int argc,
384                 char **argv, ExecutableCommand *exec, void * data)
385 {
386         struct gt_gadget_disable_data *dt;
387         int c;
388         struct option opts[] = {
389                 {"udc", required_argument, 0, 'u'},
390                 {"help", no_argument, 0, 'h'},
391                 {0, 0, 0, 0}
392         };
393
394         dt = zalloc(sizeof(*dt));
395         if (dt == NULL)
396                 goto out;
397         argv--;
398         argc++;
399         while (1) {
400                 int opt_index = 0;
401                 c = getopt_long(argc, argv, "u:h", opts, &opt_index);
402                 if (c == -1)
403                         break;
404                 switch (c) {
405                 case 'u':
406                         dt->udc = optarg;
407                         break;
408                 case 'h':
409                         goto out;
410                         break;
411                 default:
412                         goto out;
413                 }
414         }
415
416         if (optind < argc - 1 || (dt->udc && optind < argc)) {
417                 printf("Too many arguments\n");
418                 goto out;
419         }
420
421         dt->gadget = argv[optind];
422         executable_command_set(exec, GET_EXECUTABLE(disable), (void *)dt, free);
423         return;
424 out:
425         free(dt);
426         executable_command_set(exec, cmd->printHelp, data, NULL);
427 }
428
429 static int gt_gadget_gadget_help(void *data)
430 {
431         printf("Gadget gadget help.\n");
432         return -1;
433 }
434
435 static void gt_parse_gadget_gadget(const Command *cmd, int argc,
436                 char **argv, ExecutableCommand *exec, void * data)
437 {
438         struct gt_gadget_gadget_data *dt;
439         int ind;
440         int avaible_opts = GT_RECURSIVE | GT_VERBOSE | GT_HELP;
441
442         dt = zalloc(sizeof(*dt));
443         if (dt == NULL)
444                 goto out;
445
446         ind = gt_get_options(&dt->opts, avaible_opts, argc, argv);
447         if (ind < 0 || dt->opts & GT_HELP)
448                 goto out;
449
450         switch (argc - ind) {
451         case 0:
452                 break;
453         case 1:
454                 dt->name = argv[ind];
455                 break;
456         default:
457                 goto out;
458         }
459
460         executable_command_set(exec, GET_EXECUTABLE(gadget), (void *)dt,
461                 free);
462         return;
463 out:
464         free(dt);
465         executable_command_set(exec, cmd->printHelp, data, NULL);
466 }
467
468 static int gt_gadget_load_help(void *data)
469 {
470         printf("Gadget load help\n");
471         return -1;
472 }
473
474 static void gt_parse_gadget_load(const Command *cmd, int argc,
475                 char **argv, ExecutableCommand *exec, void * data)
476 {
477         int c;
478         struct gt_gadget_load_data *dt;
479         struct option opts[] = {
480                 {"off", no_argument, 0, 'o'},
481                 {"file", required_argument, 0, 1},
482                 {"stdin", no_argument, 0, 2},
483                 {"path", required_argument, 0, 3},
484                 {"help", no_argument, 0, 'h'},
485                 {0, 0, 0, 0}
486         };
487
488         dt = zalloc(sizeof(*dt));
489         if (dt == NULL)
490                 goto out;
491         argv--;
492         argc++;
493         while (1) {
494                 int opt_index = 0;
495                 c = getopt_long(argc, argv, "oh", opts, &opt_index);
496                 if (c == -1)
497                         break;
498                 switch (c) {
499                 case 'o':
500                         dt->opts |= GT_OFF;
501                         break;
502                 case 1:
503                         if (dt->path || dt->opts & GT_STDIN)
504                                 goto out;
505                         dt->file = optarg;
506                         break;
507                 case 2:
508                         if (dt->path || dt->file)
509                                 goto out;
510                         dt->opts |= GT_STDIN;
511                         break;
512                 case 3:
513                         if (dt->file || dt->opts & GT_STDIN)
514                                 goto out;
515                         dt->path = optarg;
516                         break;
517                 case 'h':
518                         goto out;
519                         break;
520                 default:
521                         goto out;
522                 }
523         }
524
525         if (optind == argc || optind < argc - 2)
526                 goto out;
527
528         dt->name = argv[optind++];
529         if (dt->opts & GT_STDIN || dt->file) {
530                 dt->gadget_name = dt->name;
531                 dt->name = NULL;
532                 if (optind < argc)
533                         goto out;
534         }
535
536         if (optind < argc)
537                 dt->gadget_name = argv[optind++];
538
539         executable_command_set(exec, GET_EXECUTABLE(load), (void *)dt, free);
540         return;
541 out:
542         free(dt);
543         executable_command_set(exec, cmd->printHelp, data, NULL);
544 }
545
546 static void gt_gadget_save_destructor(void *data)
547 {
548         struct gt_gadget_save_data *dt;
549
550         if (data == NULL)
551                 return;
552         dt = (struct gt_gadget_save_data *)data;
553         gt_setting_list_cleanup(dt->attrs);
554         free(dt);
555 }
556
557 static int gt_gadget_save_help(void *data)
558 {
559         printf("Gadget save help.\n");
560         return -1;
561 }
562
563 static void gt_parse_gadget_save(const Command *cmd, int argc,
564                 char **argv, ExecutableCommand *exec, void * data)
565 {
566         int c;
567         struct gt_gadget_save_data *dt;
568         struct option opts[] = {
569                 {"force", no_argument, 0, 'f'},
570                 {"file", required_argument, 0, 1},
571                 {"stdout", no_argument, 0, 2},
572                 {"path", required_argument, 0, 3},
573                 {"help", no_argument, 0, 'h'},
574                 {0, 0, 0, 0}
575         };
576
577         dt = zalloc(sizeof(*dt));
578         if (dt == NULL)
579                 goto out;
580         argv--;
581         argc++;
582         while (1) {
583                 int opt_index = 0;
584                 c = getopt_long(argc, argv, "fh", opts, &opt_index);
585                 if (c == -1)
586                         break;
587                 switch (c) {
588                 case 'f':
589                         dt->opts |= GT_FORCE;
590                         break;
591                 case 1:
592                         if (dt->path || dt->opts & GT_STDOUT)
593                                 goto out;
594                         dt->file = optarg;
595                         break;
596                 case 2:
597                         if (dt->file || dt->path)
598                                 goto out;
599                         dt->opts |= GT_STDOUT;
600                         break;
601                 case 3:
602                         if (dt->file || dt->opts & GT_STDOUT)
603                                 goto out;
604                         dt->path = optarg;
605                         break;
606                 case 'h':
607                         goto out;
608                         break;
609                 default:
610                         goto out;
611                 }
612         }
613
614         if (optind == argc)
615                 goto out;
616
617         dt->gadget = argv[optind++];
618
619         if(optind < argc
620           && !dt->file
621           && !(dt->opts & GT_STDOUT)
622           && strchr(argv[optind], '=') == NULL)
623                 dt->name = argv[optind++];
624
625         c = gt_parse_setting_list(&dt->attrs, argc - optind,
626                         argv + optind);
627         if (c < 0)
628                 goto out;
629
630         executable_command_set(exec, GET_EXECUTABLE(save), (void *)dt,
631                 gt_gadget_save_destructor);
632
633         return;
634 out:
635         gt_gadget_save_destructor((void *)dt);
636         executable_command_set(exec, cmd->printHelp, data, NULL);
637 }
638
639 static int gt_gadget_template_help(void *data)
640 {
641         printf("Gadget template help.\n");
642         return -1;
643 }
644
645 static void gt_parse_gadget_template(const Command *cmd, int argc,
646                 char **argv, ExecutableCommand *exec, void * data)
647 {
648         int ind;
649         struct gt_gadget_template_data *dt;
650         int avaible_opts = GT_VERBOSE | GT_RECURSIVE | GT_HELP;
651
652         dt = zalloc(sizeof(*dt));
653         if (dt == NULL)
654                 goto out;
655
656         ind = gt_get_options(&dt->opts, avaible_opts, argc, argv);
657         if (ind < 0 || dt->opts & GT_HELP)
658                 goto out;
659
660         if (argc - ind > 1)
661                 goto out;
662
663         if (argv[ind])
664                 dt->name = argv[ind];
665
666         executable_command_set(exec, GET_EXECUTABLE(template_default), (void *)dt,
667                 free);
668
669         return;
670 out:
671         free(dt);
672         executable_command_set(exec, cmd->printHelp, data, NULL);
673 }
674
675 static int gt_gadget_template_rm_help(void *data)
676 {
677         printf("Gadget template rm help.\n");
678         return -1;
679 }
680
681 static void gt_parse_gadget_template_rm(const Command *cmd, int argc,
682                 char **argv, ExecutableCommand *exec, void * data)
683 {
684         struct gt_gadget_template_rm_data *dt = NULL;
685         int ind;
686         int avaible_opts = GT_HELP;
687
688         dt = zalloc(sizeof(*dt));
689         if (dt == NULL)
690                 goto out;
691
692         ind = gt_get_options(&dt->opts, avaible_opts, argc, argv);
693         if (ind < 0 || dt->opts & GT_HELP)
694                 goto out;
695
696         if (argc - ind != 1)
697                 goto out;
698
699         dt->name = argv[ind++];
700         executable_command_set(exec, GET_EXECUTABLE(template_rm), (void *)dt,
701                 NULL);
702
703         return;
704 out:
705         executable_command_set(exec, cmd->printHelp, data, NULL);
706 }
707
708 static void gt_gadget_template_set_destructor(void *data)
709 {
710         struct gt_gadget_template_set_data *dt;
711
712         if (data == NULL)
713                 return;
714         dt = (struct gt_gadget_template_set_data *)data;
715         gt_setting_list_cleanup(dt->attr);
716         free(dt);
717 }
718
719 static int gt_gadget_template_set_help(void *data)
720 {
721         printf("Gadget template set help.\n");
722         return -1;
723 }
724
725 static void gt_parse_gadget_template_set(const Command *cmd, int argc,
726                 char **argv, ExecutableCommand *exec, void * data)
727 {
728         int tmp;
729         struct gt_gadget_template_set_data *dt;
730         int ind;
731         int avaible_opts = GT_HELP;
732
733         dt = zalloc(sizeof(*dt));
734         if (dt == NULL)
735                 goto out;
736
737         ind = gt_get_options(&dt->opts, avaible_opts, argc, argv);
738         if (ind < 0 || dt->opts & GT_HELP)
739                 goto out;
740
741         if (argc - ind != 2)
742                 goto out;
743
744         dt->name = argv[ind++];
745         tmp = gt_parse_setting_list(&dt->attr, argc - ind, argv + ind);
746         if (tmp < 0)
747                 goto out;
748
749         executable_command_set(exec, GET_EXECUTABLE(set), (void *)dt,
750                 gt_gadget_template_set_destructor);
751
752         return;
753 out:
754         gt_gadget_template_set_destructor((void *)dt);
755         executable_command_set(exec, cmd->printHelp, data, NULL);
756 }
757
758 static void gt_gadget_template_get_destructor(void *data)
759 {
760         struct gt_gadget_template_get_data *dt;
761
762         if (data == NULL)
763                 return;
764         dt = (struct gt_gadget_template_get_data *)data;
765         free(dt->attr);
766         free(dt);
767 }
768
769 static int gt_gadget_template_get_help(void *data)
770 {
771         printf("Gadget template get help.\n");
772         return -1;
773 }
774
775 static void gt_parse_gadget_template_get(const Command *cmd, int argc,
776                 char **argv, ExecutableCommand *exec, void * data)
777 {
778         int i;
779         struct gt_gadget_template_get_data *dt;
780         int ind;
781         int avaible_opts = GT_HELP;
782
783         dt = zalloc(sizeof(*dt));
784         if (dt == NULL)
785                 goto out;
786
787         ind = gt_get_options(&dt->opts, avaible_opts, argc, argv);
788         if (ind < 0 || dt->opts & GT_HELP)
789                 goto out;
790
791         if (argc - ind < 1)
792                 goto out;
793
794         dt->name = argv[ind++];
795         dt->attr = calloc(argc, sizeof(char *));
796         if (dt->attr == NULL)
797                 goto out;
798
799         i = 0;
800         while (argv[ind])
801                 dt->attr[i++] = argv[ind++];
802
803         executable_command_set(exec, GET_EXECUTABLE(get), (void *)dt,
804                 gt_gadget_template_get_destructor);
805
806         return;
807 out:
808         gt_gadget_template_get_destructor((void *)dt);
809         executable_command_set(exec, cmd->printHelp, data, NULL);
810 }
811
812 const Command *get_gadget_template_children(const Command *cmd)
813 {
814         static Command commands[] = {
815                 {"get", NEXT, gt_parse_gadget_template_get, NULL,
816                         gt_gadget_template_get_help},
817                 {"set", NEXT, gt_parse_gadget_template_set, NULL,
818                         gt_gadget_template_set_help},
819                 {"rm", NEXT, gt_parse_gadget_template_rm, NULL,
820                         gt_gadget_template_rm_help},
821                 {NULL, AGAIN, gt_parse_gadget_template, NULL,
822                         gt_gadget_template_help},
823                 CMD_LIST_END
824         };
825
826         return commands;
827 }
828
829 const Command *get_gadget_children(const Command *cmd)
830 {
831         static Command commands[] = {
832                 {"create", NEXT, gt_parse_gadget_create, NULL,
833                         gt_gadget_create_help},
834                 {"rm", NEXT, gt_parse_gadget_rm, NULL, gt_gadget_rm_help},
835                 {"get", NEXT, gt_parse_gadget_get, NULL, gt_gadget_get_help},
836                 {"set", NEXT, gt_parse_gadget_set, NULL, gt_gadget_set_help},
837                 {"enable", NEXT, gt_parse_gadget_enable, NULL,
838                         gt_gadget_enable_help},
839                 {"disable", NEXT, gt_parse_gadget_disable, NULL,
840                         gt_gadget_disable_help},
841                 {"gadget", NEXT, gt_parse_gadget_gadget, NULL,
842                         gt_gadget_gadget_help},
843                 {"template", NEXT, command_parse, get_gadget_template_children,
844                         gt_gadget_template_help},
845                 {"load", NEXT, gt_parse_gadget_load, NULL,
846                         gt_gadget_load_help},
847                 {"save", NEXT, gt_parse_gadget_save, NULL,
848                         gt_gadget_save_help},
849                 CMD_LIST_END
850         };
851
852         return commands;
853 }
854
855 int gt_gadget_help(void *data)
856 {
857         printf("Gadget help function\n");
858         return -1;
859 }