2 * Copyright (c) 2009, Olivier MATZ <zer0@droids-corp.org>
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the University of California, Berkeley nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 #include <sys/queue.h>
36 #include <arpa/inet.h>
38 #include <linux/joystick.h>
42 #include <cmdline_parse.h>
43 #include <cmdline_parse_num.h>
44 #include <cmdline_parse_string.h>
45 #include <cmdline_parse_file.h>
48 #include "xbee_neighbor.h"
49 #include "xbee_atcmd.h"
50 #include "xbee_stats.h"
52 #include "xbee_proto.h"
54 #include "parse_atcmd.h"
55 #include "parse_neighbor.h"
56 #include "parse_monitor.h"
61 static struct monitor_reg_list monitor_list = LIST_HEAD_INITIALIZER(x/*XXX*/);
62 static int monitor_period_ms = 1000;
63 static int monitor_running = 0;
64 static int monitor_count = 0;
65 static struct event monitor_event;
66 struct monitor_reg *monitor_current;
68 static int range_period_ms = 1000;
69 static int range_powermask = 0x1F;
70 static uint8_t range_power = 0;
71 static int range_running = 0;
72 static uint64_t range_dstaddr = 0xFFFF; /* broadcast by default */
73 static struct event range_event;
74 static int range_count = 100;
75 static int range_cur_count = 0;
77 static struct event rc_send_event;
78 static int rc_send_period_ms = 100;
79 static uint64_t rc_send_dstaddr = 0xFFFF; /* broadcast by default */
80 static int rc_send_running = 0;
81 static const char *xbee_logfilename = "/tmp/xbee.log";
83 static void monitor_cb(int s, short event, void *arg)
86 struct cmdline *cl = arg;
88 if (monitor_current == NULL)
89 monitor_current = LIST_FIRST(&monitor_list);
91 xbeeapp_send_atcmd(monitor_current->atcmd, NULL, 0, 0);
92 monitor_current = LIST_NEXT(monitor_current, next);
94 evtimer_set(&monitor_event, monitor_cb, cl);
96 tv.tv_usec = (1000 * monitor_period_ms) / monitor_count;
97 evtimer_add(&monitor_event, &tv);
100 static void range_cb(int s, short event, void *arg)
103 struct cmdline *cl = arg;
109 /* get new xmit power */
110 for (i = 1; i <= 8; i++) {
111 mask = 1 << ((range_power + i) & 0x7);
112 if (mask & range_powermask)
115 range_power = ((range_power + i) & 0x7);
117 xbeeapp_send_atcmd("PL", &range_power, sizeof(range_power), 0);
118 snprintf(buf, sizeof(buf), "range%d", range_power);
119 xbeeapp_send_msg(range_dstaddr, buf, strlen(buf), 0);
121 if (range_cur_count == 0) {
126 evtimer_set(&range_event, range_cb, cl);
128 tv.tv_usec = 1000 * range_period_ms;
129 evtimer_add(&range_event, &tv);
133 static void rc_send_cb(int fd, short event, void *arg)
135 struct cmdline *cl = arg;
137 struct rc_proto_channel rc_chan;
140 rc_chan.type = RC_PROTO_TYPE_CHANNEL;
141 for (i = 0; i< AXIS_NUMBER; i++){
142 rc_chan.axis[i] = htons(joyinfo.axis[i]);
144 xbeeapp_send_msg(rc_send_dstaddr, &rc_chan, sizeof(rc_chan), 0);
146 evtimer_set(&rc_send_event, rc_send_cb, cl);
148 tv.tv_usec = 1000 * rc_send_period_ms;
149 evtimer_add(&rc_send_event, &tv);
155 /* this structure is filled when cmd_stats is parsed successfully */
156 struct cmd_stats_result {
157 cmdline_fixed_string_t stats;
158 cmdline_fixed_string_t action;
161 /* function called when cmd_stats is parsed successfully */
162 static void cmd_stats_parsed(void *parsed_result, struct cmdline *cl, void *data)
164 struct cmd_stats_result *res = parsed_result;
166 if (!strcmp(res->action, "show")) {
167 xbee_dump_stats(stdout, xbee_dev);
168 if (xbee_logfile != NULL)
169 xbee_dump_stats(xbee_logfile, xbee_dev);
171 else if (!strcmp(res->action, "reset"))
172 xbee_reset_stats(xbee_dev);
175 cmdline_parse_token_string_t cmd_stats_stats =
176 TOKEN_STRING_INITIALIZER(struct cmd_stats_result, stats, "stats");
177 cmdline_parse_token_string_t cmd_stats_action =
178 TOKEN_STRING_INITIALIZER(struct cmd_stats_result, action, "show#reset");
180 cmdline_parse_inst_t cmd_stats = {
181 .f = cmd_stats_parsed, /* function to call */
182 .data = NULL, /* 2nd arg of func */
183 .help_str = "Send a stats to the xbee device",
184 .tokens = { /* token list, NULL terminated */
185 (void *)&cmd_stats_stats,
186 (void *)&cmd_stats_action,
193 /* this structure is filled when cmd_monitor is parsed successfully */
194 struct cmd_monitor_result {
195 cmdline_fixed_string_t monitor;
196 cmdline_fixed_string_t action;
199 /* function called when cmd_monitor is parsed successfully */
200 static void cmd_monitor_parsed(void *parsed_result, struct cmdline *cl,
203 struct cmd_monitor_result *res = parsed_result;
204 struct monitor_reg *m;
206 if (!strcmp(res->action, "show")) {
207 printf("monitor period is %d ms, %d regs in list\n",
208 monitor_period_ms, monitor_count);
209 LIST_FOREACH(m, &monitor_list, next)
210 printf(" %s\n", m->desc);
212 else if (!strcmp(res->action, "start")) {
214 if (monitor_running) {
215 printf("already running\n");
218 if (monitor_count == 0) {
219 printf("no regs to be monitored\n");
222 evtimer_set(&monitor_event, monitor_cb, cl);
225 evtimer_add(&monitor_event, &tv);
227 monitor_current = LIST_FIRST(&monitor_list);
229 else if (!strcmp(res->action, "end")) {
230 if (monitor_running == 0) {
231 printf("not running\n");
235 evtimer_del(&monitor_event);
239 cmdline_parse_token_string_t cmd_monitor_monitor =
240 TOKEN_STRING_INITIALIZER(struct cmd_monitor_result, monitor, "monitor");
241 cmdline_parse_token_string_t cmd_monitor_action =
242 TOKEN_STRING_INITIALIZER(struct cmd_monitor_result, action,
245 cmdline_parse_inst_t cmd_monitor = {
246 .f = cmd_monitor_parsed, /* function to call */
247 .data = NULL, /* 2nd arg of func */
248 .help_str = "start/stop/show current monitoring",
249 .tokens = { /* token list, NULL terminated */
250 (void *)&cmd_monitor_monitor,
251 (void *)&cmd_monitor_action,
258 /* this structure is filled when cmd_monitor_add is parsed successfully */
259 struct cmd_monitor_add_result {
260 cmdline_fixed_string_t monitor;
261 cmdline_fixed_string_t action;
262 struct xbee_atcmd *cmd;
265 /* function called when cmd_monitor_add is parsed successfully */
266 static void cmd_monitor_add_parsed(void *parsed_result, struct cmdline *cl,
269 struct cmd_monitor_add_result *res = parsed_result;
270 struct monitor_reg *m;
272 LIST_FOREACH(m, &monitor_list, next) {
273 if (!strcmp(m->desc, res->cmd->desc))
278 printf("already exist\n");
282 m = malloc(sizeof(*m));
288 m->desc = res->cmd->desc;
289 m->atcmd = res->cmd->name;
290 LIST_INSERT_HEAD(&monitor_list, m, next);
294 cmdline_parse_token_string_t cmd_monitor_add_monitor_add =
295 TOKEN_STRING_INITIALIZER(struct cmd_monitor_add_result, monitor,
297 cmdline_parse_token_string_t cmd_monitor_add_action =
298 TOKEN_STRING_INITIALIZER(struct cmd_monitor_add_result, action,
300 parse_token_atcmd_t cmd_monitor_add_atcmd =
301 TOKEN_ATCMD_INITIALIZER(struct cmd_monitor_add_result, cmd, &xbee_dev,
302 XBEE_ATCMD_F_READ, XBEE_ATCMD_F_READ);
305 cmdline_parse_inst_t cmd_monitor_add = {
306 .f = cmd_monitor_add_parsed, /* function to call */
307 .data = NULL, /* 2nd arg of func */
308 .help_str = "add a register in monitor list",
309 .tokens = { /* token list, NULL terminated */
310 (void *)&cmd_monitor_add_monitor_add,
311 (void *)&cmd_monitor_add_action,
312 (void *)&cmd_monitor_add_atcmd,
319 /* this structure is filled when cmd_monitor_period is parsed successfully */
320 struct cmd_monitor_period_result {
321 cmdline_fixed_string_t monitor;
322 cmdline_fixed_string_t action;
326 /* function called when cmd_monitor_period is parsed successfully */
327 static void cmd_monitor_period_parsed(void *parsed_result, struct cmdline *cl,
330 struct cmd_monitor_period_result *res = parsed_result;
332 if (res->period < 100) {
333 printf("error, minimum period is 100 ms\n");
337 monitor_period_ms = res->period;
340 cmdline_parse_token_string_t cmd_monitor_period_monitor_period =
341 TOKEN_STRING_INITIALIZER(struct cmd_monitor_period_result, monitor,
343 cmdline_parse_token_string_t cmd_monitor_period_action =
344 TOKEN_STRING_INITIALIZER(struct cmd_monitor_period_result, action,
346 cmdline_parse_token_num_t cmd_monitor_period_period =
347 TOKEN_NUM_INITIALIZER(struct cmd_monitor_period_result, period, UINT32);
350 cmdline_parse_inst_t cmd_monitor_period = {
351 .f = cmd_monitor_period_parsed, /* function to call */
352 .data = NULL, /* 2nd arg of func */
353 .help_str = "set register monitoring period",
354 .tokens = { /* token list, NULL terminated */
355 (void *)&cmd_monitor_period_monitor_period,
356 (void *)&cmd_monitor_period_action,
357 (void *)&cmd_monitor_period_period,
364 /* this structure is filled when cmd_monitor_del is parsed successfully */
365 struct cmd_monitor_del_result {
366 cmdline_fixed_string_t monitor;
367 cmdline_fixed_string_t action;
368 struct monitor_reg *m;
371 /* function called when cmd_monitor_del is parsed successfully */
372 static void cmd_monitor_del_parsed(void *parsed_result, struct cmdline *cl,
375 struct cmd_monitor_del_result *res = parsed_result;
377 monitor_current = LIST_NEXT(res->m, next);
378 LIST_REMOVE(res->m, next);
381 if (monitor_count == 0) {
382 printf("Disable monitoring, no more event\n");
383 evtimer_del(&monitor_event);
389 cmdline_parse_token_string_t cmd_monitor_del_monitor_del =
390 TOKEN_STRING_INITIALIZER(struct cmd_monitor_del_result, monitor,
392 cmdline_parse_token_string_t cmd_monitor_del_action =
393 TOKEN_STRING_INITIALIZER(struct cmd_monitor_del_result, action,
395 parse_token_monitor_t cmd_monitor_del_atcmd =
396 TOKEN_MONITOR_INITIALIZER(struct cmd_monitor_del_result, m,
400 cmdline_parse_inst_t cmd_monitor_del = {
401 .f = cmd_monitor_del_parsed, /* function to call */
402 .data = NULL, /* 2nd arg of func */
403 .help_str = "del a register in monitor list",
404 .tokens = { /* token list, NULL terminated */
405 (void *)&cmd_monitor_del_monitor_del,
406 (void *)&cmd_monitor_del_action,
407 (void *)&cmd_monitor_del_atcmd,
414 /* this structure is filled when cmd_range is parsed successfully */
415 struct cmd_range_result {
416 cmdline_fixed_string_t range;
417 cmdline_fixed_string_t action;
420 /* function called when cmd_range is parsed successfully */
421 static void cmd_range_parsed(void *parsed_result, struct cmdline *cl,
424 struct cmd_range_result *res = parsed_result;
426 if (!strcmp(res->action, "show")) {
427 printf("range infos:\n");
428 printf(" range period %d\n", range_period_ms);
429 printf(" range count %d\n", range_count);
430 printf(" range powermask 0x%x\n", range_powermask);
431 printf(" range dstaddr %"PRIx64"\n", range_dstaddr);
433 printf(" range test is running\n");
435 printf(" range test is not running\n");
437 else if (!strcmp(res->action, "start")) {
440 printf("already running\n");
443 range_cur_count = range_count;
444 evtimer_set(&range_event, range_cb, cl);
447 evtimer_add(&range_event, &tv);
450 else if (!strcmp(res->action, "end")) {
451 if (range_running == 0) {
452 printf("not running\n");
456 evtimer_del(&range_event);
460 cmdline_parse_token_string_t cmd_range_range =
461 TOKEN_STRING_INITIALIZER(struct cmd_range_result, range, "range");
462 cmdline_parse_token_string_t cmd_range_action =
463 TOKEN_STRING_INITIALIZER(struct cmd_range_result, action,
466 cmdline_parse_inst_t cmd_range = {
467 .f = cmd_range_parsed, /* function to call */
468 .data = NULL, /* 2nd arg of func */
469 .help_str = "start/stop/show current rangeing",
470 .tokens = { /* token list, NULL terminated */
471 (void *)&cmd_range_range,
472 (void *)&cmd_range_action,
479 /* this structure is filled when cmd_range_period is parsed successfully */
480 struct cmd_range_period_result {
481 cmdline_fixed_string_t range;
482 cmdline_fixed_string_t action;
486 /* function called when cmd_range_period is parsed successfully */
487 static void cmd_range_period_parsed(void *parsed_result, struct cmdline *cl,
490 struct cmd_range_period_result *res = parsed_result;
492 if (res->period < 10) {
493 printf("error, minimum period is 10 ms\n");
497 range_period_ms = res->period;
500 cmdline_parse_token_string_t cmd_range_period_range_period =
501 TOKEN_STRING_INITIALIZER(struct cmd_range_period_result, range,
503 cmdline_parse_token_string_t cmd_range_period_action =
504 TOKEN_STRING_INITIALIZER(struct cmd_range_period_result, action,
506 cmdline_parse_token_num_t cmd_range_period_period =
507 TOKEN_NUM_INITIALIZER(struct cmd_range_period_result, period, UINT32);
510 cmdline_parse_inst_t cmd_range_period = {
511 .f = cmd_range_period_parsed, /* function to call */
512 .data = NULL, /* 2nd arg of func */
513 .help_str = "set range test period",
514 .tokens = { /* token list, NULL terminated */
515 (void *)&cmd_range_period_range_period,
516 (void *)&cmd_range_period_action,
517 (void *)&cmd_range_period_period,
524 /* this structure is filled when cmd_range_count is parsed successfully */
525 struct cmd_range_count_result {
526 cmdline_fixed_string_t range;
527 cmdline_fixed_string_t action;
531 /* function called when cmd_range_count is parsed successfully */
532 static void cmd_range_count_parsed(void *parsed_result, struct cmdline *cl,
535 struct cmd_range_count_result *res = parsed_result;
536 range_count = res->count;
539 cmdline_parse_token_string_t cmd_range_count_range_count =
540 TOKEN_STRING_INITIALIZER(struct cmd_range_count_result, range,
542 cmdline_parse_token_string_t cmd_range_count_action =
543 TOKEN_STRING_INITIALIZER(struct cmd_range_count_result, action,
545 cmdline_parse_token_num_t cmd_range_count_count =
546 TOKEN_NUM_INITIALIZER(struct cmd_range_count_result, count, UINT32);
549 cmdline_parse_inst_t cmd_range_count = {
550 .f = cmd_range_count_parsed, /* function to call */
551 .data = NULL, /* 2nd arg of func */
552 .help_str = "set range test count",
553 .tokens = { /* token list, NULL terminated */
554 (void *)&cmd_range_count_range_count,
555 (void *)&cmd_range_count_action,
556 (void *)&cmd_range_count_count,
563 /* this structure is filled when cmd_range_powermask is parsed successfully */
564 struct cmd_range_powermask_result {
565 cmdline_fixed_string_t range;
566 cmdline_fixed_string_t action;
570 /* function called when cmd_range_powermask is parsed successfully */
571 static void cmd_range_powermask_parsed(void *parsed_result, struct cmdline *cl,
574 struct cmd_range_powermask_result *res = parsed_result;
575 range_powermask = res->powermask;
578 cmdline_parse_token_string_t cmd_range_powermask_range_powermask =
579 TOKEN_STRING_INITIALIZER(struct cmd_range_powermask_result, range,
581 cmdline_parse_token_string_t cmd_range_powermask_action =
582 TOKEN_STRING_INITIALIZER(struct cmd_range_powermask_result, action,
584 cmdline_parse_token_num_t cmd_range_powermask_powermask =
585 TOKEN_NUM_INITIALIZER(struct cmd_range_powermask_result, powermask,
589 cmdline_parse_inst_t cmd_range_powermask = {
590 .f = cmd_range_powermask_parsed, /* function to call */
591 .data = NULL, /* 2nd arg of func */
592 .help_str = "set range test powermask",
593 .tokens = { /* token list, NULL terminated */
594 (void *)&cmd_range_powermask_range_powermask,
595 (void *)&cmd_range_powermask_action,
596 (void *)&cmd_range_powermask_powermask,
603 /* this structure is filled when cmd_range_dstaddr is parsed successfully */
604 struct cmd_range_dstaddr_result {
605 cmdline_fixed_string_t range;
606 cmdline_fixed_string_t action;
610 /* function called when cmd_range_dstaddr is parsed successfully */
611 static void cmd_range_dstaddr_parsed(void *parsed_result, struct cmdline *cl,
614 struct cmd_range_dstaddr_result *res = parsed_result;
616 range_dstaddr = res->dstaddr;
619 cmdline_parse_token_string_t cmd_range_dstaddr_range_dstaddr =
620 TOKEN_STRING_INITIALIZER(struct cmd_range_dstaddr_result, range,
622 cmdline_parse_token_string_t cmd_range_dstaddr_action =
623 TOKEN_STRING_INITIALIZER(struct cmd_range_dstaddr_result, action,
625 cmdline_parse_token_num_t cmd_range_dstaddr_dstaddr =
626 TOKEN_NUM_INITIALIZER(struct cmd_range_dstaddr_result, dstaddr, UINT64);
629 cmdline_parse_inst_t cmd_range_dstaddr = {
630 .f = cmd_range_dstaddr_parsed, /* function to call */
631 .data = NULL, /* 2nd arg of func */
632 .help_str = "set register rangeing dstaddr",
633 .tokens = { /* token list, NULL terminated */
634 (void *)&cmd_range_dstaddr_range_dstaddr,
635 (void *)&cmd_range_dstaddr_action,
636 (void *)&cmd_range_dstaddr_dstaddr,
643 /* this structure is filled when cmd_rc_send is parsed successfully */
644 struct cmd_rc_send_result {
645 cmdline_fixed_string_t rc_send;
646 cmdline_fixed_string_t action;
649 /* function called when cmd_rc_send is parsed successfully */
650 static void cmd_rc_send_parsed(void *parsed_result, struct cmdline *cl,
653 struct cmd_rc_send_result *res = parsed_result;
655 if (!strcmp(res->action, "show"))
657 else if (!strcmp(res->action, "start")) {
659 if (rc_send_running) {
660 printf("already running\n");
663 evtimer_set(&rc_send_event, rc_send_cb, cl);
666 evtimer_add(&rc_send_event, &tv);
669 else if (!strcmp(res->action, "end")) {
670 if (rc_send_running == 0) {
671 printf("not running\n");
675 evtimer_del(&rc_send_event);
679 cmdline_parse_token_string_t cmd_rc_send_rc_send =
680 TOKEN_STRING_INITIALIZER(struct cmd_rc_send_result, rc_send, "rc_send");
681 cmdline_parse_token_string_t cmd_rc_send_action =
682 TOKEN_STRING_INITIALIZER(struct cmd_rc_send_result, action,
685 cmdline_parse_inst_t cmd_rc_send = {
686 .f = cmd_rc_send_parsed, /* function to call */
687 .data = NULL, /* 2nd arg of func */
688 .help_str = "start/stop/show current rc_sending",
689 .tokens = { /* token list, NULL terminated */
690 (void *)&cmd_rc_send_rc_send,
691 (void *)&cmd_rc_send_action,
698 /* this structure is filled when cmd_rc_send_period is parsed successfully */
699 struct cmd_rc_send_period_result {
700 cmdline_fixed_string_t rc_send;
701 cmdline_fixed_string_t action;
705 /* function called when cmd_rc_send_period is parsed successfully */
706 static void cmd_rc_send_period_parsed(void *parsed_result, struct cmdline *cl,
709 struct cmd_rc_send_period_result *res = parsed_result;
711 if (res->period < 10) {
712 printf("error, minimum period is 10 ms\n");
716 rc_send_period_ms = res->period;
719 cmdline_parse_token_string_t cmd_rc_send_period_rc_send_period =
720 TOKEN_STRING_INITIALIZER(struct cmd_rc_send_period_result, rc_send,
722 cmdline_parse_token_string_t cmd_rc_send_period_action =
723 TOKEN_STRING_INITIALIZER(struct cmd_rc_send_period_result, action,
725 cmdline_parse_token_num_t cmd_rc_send_period_period =
726 TOKEN_NUM_INITIALIZER(struct cmd_rc_send_period_result, period, UINT32);
729 cmdline_parse_inst_t cmd_rc_send_period = {
730 .f = cmd_rc_send_period_parsed, /* function to call */
731 .data = NULL, /* 2nd arg of func */
732 .help_str = "set register rc_sending period",
733 .tokens = { /* token list, NULL terminated */
734 (void *)&cmd_rc_send_period_rc_send_period,
735 (void *)&cmd_rc_send_period_action,
736 (void *)&cmd_rc_send_period_period,
743 /* this structure is filled when cmd_rc_send_dstaddr is parsed successfully */
744 struct cmd_rc_send_dstaddr_result {
745 cmdline_fixed_string_t rc_send;
746 cmdline_fixed_string_t action;
750 /* function called when cmd_rc_send_dstaddr is parsed successfully */
751 static void cmd_rc_send_dstaddr_parsed(void *parsed_result, struct cmdline *cl,
754 struct cmd_rc_send_dstaddr_result *res = parsed_result;
756 rc_send_dstaddr = res->dstaddr;
759 cmdline_parse_token_string_t cmd_rc_send_dstaddr_rc_send_dstaddr =
760 TOKEN_STRING_INITIALIZER(struct cmd_rc_send_dstaddr_result, rc_send,
762 cmdline_parse_token_string_t cmd_rc_send_dstaddr_action =
763 TOKEN_STRING_INITIALIZER(struct cmd_rc_send_dstaddr_result, action,
765 cmdline_parse_token_num_t cmd_rc_send_dstaddr_dstaddr =
766 TOKEN_NUM_INITIALIZER(struct cmd_rc_send_dstaddr_result, dstaddr, UINT64);
769 cmdline_parse_inst_t cmd_rc_send_dstaddr = {
770 .f = cmd_rc_send_dstaddr_parsed, /* function to call */
771 .data = NULL, /* 2nd arg of func */
772 .help_str = "set register rc_sending dstaddr",
773 .tokens = { /* token list, NULL terminated */
774 (void *)&cmd_rc_send_dstaddr_rc_send_dstaddr,
775 (void *)&cmd_rc_send_dstaddr_action,
776 (void *)&cmd_rc_send_dstaddr_dstaddr,
785 /* this structure is filled when cmd_ping is parsed successfully */
786 struct cmd_ping_result {
787 cmdline_fixed_string_t ping;
790 /* function called when cmd_ping is parsed successfully */
791 static void cmd_ping_parsed(void *parsed_result, struct cmdline *cl, void *data)
793 xbeeapp_send_atcmd("VL", NULL, 0, 1);
796 cmdline_parse_token_string_t cmd_ping_ping =
797 TOKEN_STRING_INITIALIZER(struct cmd_ping_result, ping, "ping");
799 cmdline_parse_inst_t cmd_ping = {
800 .f = cmd_ping_parsed, /* function to call */
801 .data = NULL, /* 2nd arg of func */
802 .help_str = "Send a ping to the xbee device",
803 .tokens = { /* token list, NULL terminated */
804 (void *)&cmd_ping_ping,
811 /* this structure is filled when cmd_raw is parsed successfully */
812 struct cmd_raw_result {
813 cmdline_fixed_string_t raw;
816 /* function called when cmd_raw is parsed successfully */
817 static void cmd_raw_parsed(void *parsed_result, struct cmdline *cl, void *data)
819 printf("switched to raw mode, CTRL-D to exit\n");
820 rdline_stop(&cl->rdl); /* don't display prompt when return */
824 cmdline_parse_token_string_t cmd_raw_raw =
825 TOKEN_STRING_INITIALIZER(struct cmd_raw_result, raw, "raw");
827 cmdline_parse_inst_t cmd_raw = {
828 .f = cmd_raw_parsed, /* function to call */
829 .data = NULL, /* 2nd arg of func */
830 .help_str = "Switch to raw mode",
831 .tokens = { /* token list, NULL terminated */
832 (void *)&cmd_raw_raw,
839 /* this structure is filled when cmd_dump is parsed successfully */
840 struct cmd_dump_result {
841 cmdline_fixed_string_t dump;
842 cmdline_fixed_string_t onoff;
845 /* function called when cmd_dump is parsed successfully */
846 static void cmd_dump_parsed(void *parsed_result, struct cmdline *cl, void *data)
848 struct cmd_dump_result *res = parsed_result;
849 if (!strcmp(res->onoff, "on"))
855 cmdline_parse_token_string_t cmd_dump_dump =
856 TOKEN_STRING_INITIALIZER(struct cmd_dump_result, dump, "dump");
858 cmdline_parse_token_string_t cmd_dump_onoff =
859 TOKEN_STRING_INITIALIZER(struct cmd_dump_result, onoff, "on#off");
861 cmdline_parse_inst_t cmd_dump = {
862 .f = cmd_dump_parsed, /* function to call */
863 .data = NULL, /* 2nd arg of func */
864 .help_str = "enable/disable hexdump of received packets",
865 .tokens = { /* token list, NULL terminated */
866 (void *)&cmd_dump_dump,
867 (void *)&cmd_dump_onoff,
874 /* this structure is filled when cmd_debug is parsed successfully */
875 struct cmd_debug_result {
876 cmdline_fixed_string_t debug;
877 cmdline_fixed_string_t onoff;
880 /* function called when cmd_debug is parsed successfully */
881 static void cmd_debug_parsed(void *parsed_result, struct cmdline *cl, void *data)
883 struct cmd_debug_result *res = parsed_result;
884 if (!strcmp(res->onoff, "on"))
890 cmdline_parse_token_string_t cmd_debug_debug =
891 TOKEN_STRING_INITIALIZER(struct cmd_debug_result, debug, "debug");
893 cmdline_parse_token_string_t cmd_debug_onoff =
894 TOKEN_STRING_INITIALIZER(struct cmd_debug_result, onoff, "on#off");
896 cmdline_parse_inst_t cmd_debug = {
897 .f = cmd_debug_parsed, /* function to call */
898 .data = NULL, /* 2nd arg of func */
899 .help_str = "enable/disable additionnal debug",
900 .tokens = { /* token list, NULL terminated */
901 (void *)&cmd_debug_debug,
902 (void *)&cmd_debug_onoff,
909 /* this structure is filled when cmd_help is parsed successfully */
910 struct cmd_help_result {
911 cmdline_fixed_string_t help;
912 struct xbee_atcmd *cmd;
915 /* function called when cmd_help is parsed successfully */
916 static void cmd_help_parsed(void *parsed_result, struct cmdline *cl,
919 struct cmd_help_result *res = parsed_result;
922 type = (res->cmd->flags & (XBEE_ATCMD_F_READ | XBEE_ATCMD_F_WRITE));
924 case XBEE_ATCMD_F_READ:
925 printf("Read-only\n");
927 case XBEE_ATCMD_F_WRITE:
928 printf("Write-only\n");
931 printf("Read-write\n");
934 if (res->cmd->flags & XBEE_ATCMD_F_PARAM_NONE)
935 printf("No argument\n");
936 else if (res->cmd->flags & XBEE_ATCMD_F_PARAM_U8)
937 printf("Register is unsigned 8 bits\n");
938 else if (res->cmd->flags & XBEE_ATCMD_F_PARAM_U16)
939 printf("Register is unsigned 16 bits\n");
940 else if (res->cmd->flags & XBEE_ATCMD_F_PARAM_U32)
941 printf("Register is unsigned 32 bits\n");
942 else if (res->cmd->flags & XBEE_ATCMD_F_PARAM_S16)
943 printf("Register is signed 16 bits\n");
944 else if (res->cmd->flags & XBEE_ATCMD_F_PARAM_STRING_20B)
945 printf("Register is a 20 bytes string\n");
947 printf("Unknown argument\n");
949 printf("%s\n", res->cmd->help);
952 cmdline_parse_token_string_t cmd_help_help =
953 TOKEN_STRING_INITIALIZER(struct cmd_help_result, help, "help");
955 parse_token_atcmd_t cmd_help_atcmd =
956 TOKEN_ATCMD_INITIALIZER(struct cmd_help_result, cmd, &xbee_dev,
959 cmdline_parse_inst_t cmd_help = {
960 .f = cmd_help_parsed, /* function to call */
961 .data = NULL, /* 2nd arg of func */
962 .help_str = "Help a register using an AT command",
963 .tokens = { /* token list, NULL terminated */
964 (void *)&cmd_help_help,
965 (void *)&cmd_help_atcmd,
972 /* this structure is filled when cmd_read is parsed successfully */
973 struct cmd_read_result {
974 cmdline_fixed_string_t read;
975 struct xbee_atcmd *cmd;
978 /* function called when cmd_read is parsed successfully */
979 static void cmd_read_parsed(void *parsed_result, struct cmdline *cl,
982 struct cmd_read_result *res = parsed_result;
983 xbeeapp_send_atcmd(res->cmd->name, NULL, 0, 1);
986 cmdline_parse_token_string_t cmd_read_read =
987 TOKEN_STRING_INITIALIZER(struct cmd_read_result, read, "read");
989 parse_token_atcmd_t cmd_read_atcmd =
990 TOKEN_ATCMD_INITIALIZER(struct cmd_read_result, cmd, &xbee_dev,
991 XBEE_ATCMD_F_READ, XBEE_ATCMD_F_READ);
993 cmdline_parse_inst_t cmd_read = {
994 .f = cmd_read_parsed, /* function to call */
995 .data = NULL, /* 2nd arg of func */
996 .help_str = "Read a register using an AT command",
997 .tokens = { /* token list, NULL terminated */
998 (void *)&cmd_read_read,
999 (void *)&cmd_read_atcmd,
1006 /* this structure is filled when cmd_write is parsed successfully */
1007 struct cmd_write_result {
1008 cmdline_fixed_string_t write;
1009 struct xbee_atcmd *cmd;
1017 /* function called when cmd_write is parsed successfully */
1018 static void cmd_write_parsed(void *parsed_result, struct cmdline *cl,
1021 struct cmd_write_result *res = parsed_result;
1025 if (res->cmd->flags & XBEE_ATCMD_F_PARAM_NONE) {
1029 else if (res->cmd->flags & XBEE_ATCMD_F_PARAM_U8) {
1030 len = sizeof(res->u8);
1033 else if (res->cmd->flags & XBEE_ATCMD_F_PARAM_U16) {
1034 len = sizeof(res->u16);
1035 res->u16 = htons(res->u16);
1038 else if (res->cmd->flags & XBEE_ATCMD_F_PARAM_U32) {
1039 len = sizeof(res->u32);
1040 res->u32 = htonl(res->u32);
1044 printf("Unknown argument type\n");
1047 xbeeapp_send_atcmd(res->cmd->name, param, len, 1);
1050 cmdline_parse_token_string_t cmd_write_write =
1051 TOKEN_STRING_INITIALIZER(struct cmd_write_result, write,
1054 parse_token_atcmd_t cmd_write_none_atcmd =
1055 TOKEN_ATCMD_INITIALIZER(struct cmd_write_result, cmd,
1057 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_NONE,
1058 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_NONE);
1060 cmdline_parse_inst_t cmd_write_none = {
1061 .f = cmd_write_parsed, /* function to call */
1062 .data = NULL, /* 2nd arg of func */
1063 .help_str = "Send an AT command (no argument)",
1064 .tokens = { /* token list, NULL terminated */
1065 (void *)&cmd_write_write,
1066 (void *)&cmd_write_none_atcmd,
1071 parse_token_atcmd_t cmd_write_u8_atcmd =
1072 TOKEN_ATCMD_INITIALIZER(struct cmd_write_result, cmd,
1074 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U8,
1075 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U8);
1077 cmdline_parse_token_num_t cmd_write_u8_u8 =
1078 TOKEN_NUM_INITIALIZER(struct cmd_write_result, u8, UINT8);
1080 cmdline_parse_inst_t cmd_write_u8 = {
1081 .f = cmd_write_parsed, /* function to call */
1082 .data = NULL, /* 2nd arg of func */
1083 .help_str = "Write a 8 bits register using an AT command",
1084 .tokens = { /* token list, NULL terminated */
1085 (void *)&cmd_write_write,
1086 (void *)&cmd_write_u8_atcmd,
1087 (void *)&cmd_write_u8_u8,
1092 parse_token_atcmd_t cmd_write_u16_atcmd =
1093 TOKEN_ATCMD_INITIALIZER(struct cmd_write_result, cmd,
1095 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U16,
1096 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U16);
1098 cmdline_parse_token_num_t cmd_write_u16_u16 =
1099 TOKEN_NUM_INITIALIZER(struct cmd_write_result, u16, UINT16);
1101 cmdline_parse_inst_t cmd_write_u16 = {
1102 .f = cmd_write_parsed, /* function to call */
1103 .data = NULL, /* 2nd arg of func */
1104 .help_str = "Write a 16 bits register using an AT command",
1105 .tokens = { /* token list, NULL terminated */
1106 (void *)&cmd_write_write,
1107 (void *)&cmd_write_u16_atcmd,
1108 (void *)&cmd_write_u16_u16,
1113 parse_token_atcmd_t cmd_write_u32_atcmd =
1114 TOKEN_ATCMD_INITIALIZER(struct cmd_write_result, cmd,
1116 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U32,
1117 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U32);
1119 cmdline_parse_token_num_t cmd_write_u32_u32 =
1120 TOKEN_NUM_INITIALIZER(struct cmd_write_result, u32, UINT32);
1122 cmdline_parse_inst_t cmd_write_u32 = {
1123 .f = cmd_write_parsed, /* function to call */
1124 .data = NULL, /* 2nd arg of func */
1125 .help_str = "Write a 32 bits register using an AT command",
1126 .tokens = { /* token list, NULL terminated */
1127 (void *)&cmd_write_write,
1128 (void *)&cmd_write_u32_atcmd,
1129 (void *)&cmd_write_u32_u32,
1136 /* this structure is filled when cmd_sendmsg is parsed successfully */
1137 struct cmd_sendmsg_result {
1138 cmdline_fixed_string_t sendmsg;
1140 cmdline_fixed_string_t data;
1143 /* function called when cmd_sendmsg is parsed successfully */
1144 static void cmd_sendmsg_parsed(void *parsed_result, struct cmdline *cl,
1147 struct cmd_sendmsg_result *res = parsed_result;
1148 xbeeapp_send_msg(res->addr, res->data, strlen(res->data), 1);
1151 cmdline_parse_token_string_t cmd_sendmsg_sendmsg =
1152 TOKEN_STRING_INITIALIZER(struct cmd_sendmsg_result, sendmsg, "sendmsg");
1154 cmdline_parse_token_num_t cmd_sendmsg_addr =
1155 TOKEN_NUM_INITIALIZER(struct cmd_sendmsg_result, addr, UINT64);
1157 cmdline_parse_token_string_t cmd_sendmsg_data =
1158 TOKEN_STRING_INITIALIZER(struct cmd_sendmsg_result, data, NULL);
1160 cmdline_parse_inst_t cmd_sendmsg = {
1161 .f = cmd_sendmsg_parsed, /* function to call */
1162 .data = NULL, /* 2nd arg of func */
1163 .help_str = "Send data to a node using its address",
1164 .tokens = { /* token list, NULL terminated */
1165 (void *)&cmd_sendmsg_sendmsg,
1166 (void *)&cmd_sendmsg_addr,
1167 (void *)&cmd_sendmsg_data,
1174 /* this structure is filled when cmd_sendmsg_name is parsed successfully */
1175 struct cmd_sendmsg_name_result {
1176 cmdline_fixed_string_t sendmsg_name;
1177 struct xbee_neigh *neigh;
1178 cmdline_fixed_string_t data;
1181 /* function called when cmd_sendmsg_name is parsed successfully */
1182 static void cmd_sendmsg_name_parsed(void *parsed_result, struct cmdline *cl,
1185 struct cmd_sendmsg_name_result *res = parsed_result;
1186 xbeeapp_send_msg(res->neigh->addr, res->data, strlen(res->data), 1);
1189 cmdline_parse_token_string_t cmd_sendmsg_name_sendmsg_name =
1190 TOKEN_STRING_INITIALIZER(struct cmd_sendmsg_name_result, sendmsg_name,
1193 parse_token_neighbor_t cmd_sendmsg_name_neigh =
1194 TOKEN_NEIGHBOR_INITIALIZER(struct cmd_sendmsg_name_result, neigh,
1197 cmdline_parse_token_string_t cmd_sendmsg_name_data =
1198 TOKEN_STRING_INITIALIZER(struct cmd_sendmsg_name_result, data, NULL);
1200 cmdline_parse_inst_t cmd_sendmsg_name = {
1201 .f = cmd_sendmsg_name_parsed, /* function to call */
1202 .data = NULL, /* 2nd arg of func */
1203 .help_str = "Send data to a node using its name",
1204 .tokens = { /* token list, NULL terminated */
1205 (void *)&cmd_sendmsg_name_sendmsg_name,
1206 (void *)&cmd_sendmsg_name_neigh,
1207 (void *)&cmd_sendmsg_name_data,
1214 struct cmd_neigh_del_result {
1215 cmdline_fixed_string_t cmd;
1216 cmdline_fixed_string_t action;
1217 struct xbee_neigh *neigh;
1220 static void cmd_neigh_del_parsed(void *parsed_result,
1224 struct cmd_neigh_del_result *res = parsed_result;
1225 xbee_neigh_del(xbee_dev, res->neigh);
1228 cmdline_parse_token_string_t cmd_neigh_del_cmd =
1229 TOKEN_STRING_INITIALIZER(struct cmd_neigh_del_result, cmd, "neigh");
1230 cmdline_parse_token_string_t cmd_neigh_del_action =
1231 TOKEN_STRING_INITIALIZER(struct cmd_neigh_del_result, action, "del");
1232 parse_token_neighbor_t cmd_neigh_del_neigh =
1233 TOKEN_NEIGHBOR_INITIALIZER(struct cmd_neigh_del_result, neigh,
1236 cmdline_parse_inst_t cmd_neigh_del = {
1237 .f = cmd_neigh_del_parsed, /* function to call */
1238 .data = NULL, /* 2nd arg of func */
1239 .help_str = "delete a neighbor",
1240 .tokens = { /* token list, NULL terminated */
1241 (void *)&cmd_neigh_del_cmd,
1242 (void *)&cmd_neigh_del_action,
1243 (void *)&cmd_neigh_del_neigh,
1250 struct cmd_neigh_add_result {
1251 cmdline_fixed_string_t cmd;
1252 cmdline_fixed_string_t action;
1253 cmdline_fixed_string_t name;
1257 static void cmd_neigh_add_parsed(void *parsed_result,
1261 struct cmd_neigh_add_result *res = parsed_result;
1262 if (xbee_neigh_add(xbee_dev, res->name, res->addr) == NULL)
1263 printf("name or addr already exist\n");
1266 cmdline_parse_token_string_t cmd_neigh_add_cmd =
1267 TOKEN_STRING_INITIALIZER(struct cmd_neigh_add_result, cmd, "neigh");
1268 cmdline_parse_token_string_t cmd_neigh_add_action =
1269 TOKEN_STRING_INITIALIZER(struct cmd_neigh_add_result, action, "add");
1270 cmdline_parse_token_string_t cmd_neigh_add_name =
1271 TOKEN_STRING_INITIALIZER(struct cmd_neigh_add_result, name, NULL);
1272 cmdline_parse_token_num_t cmd_neigh_add_addr =
1273 TOKEN_NUM_INITIALIZER(struct cmd_neigh_add_result, addr, UINT64);
1275 cmdline_parse_inst_t cmd_neigh_add = {
1276 .f = cmd_neigh_add_parsed, /* function to call */
1277 .data = NULL, /* 2nd arg of func */
1278 .help_str = "add a neighbor",
1279 .tokens = { /* token list, NULL terminated */
1280 (void *)&cmd_neigh_add_cmd,
1281 (void *)&cmd_neigh_add_action,
1282 (void *)&cmd_neigh_add_name,
1283 (void *)&cmd_neigh_add_addr,
1290 struct cmd_neigh_list_result {
1291 cmdline_fixed_string_t cmd;
1292 cmdline_fixed_string_t action;
1295 static void cmd_neigh_list_parsed(void *parsed_result,
1299 struct xbee_neigh *neigh;
1301 LIST_FOREACH(neigh, &xbee_dev->neigh_list, next) {
1302 printf(" %s: 0x%"PRIx64"\n", neigh->name, neigh->addr);
1306 cmdline_parse_token_string_t cmd_neigh_list_cmd =
1307 TOKEN_STRING_INITIALIZER(struct cmd_neigh_list_result, cmd, "neigh");
1308 cmdline_parse_token_string_t cmd_neigh_list_action =
1309 TOKEN_STRING_INITIALIZER(struct cmd_neigh_list_result, action, "list");
1311 cmdline_parse_inst_t cmd_neigh_list = {
1312 .f = cmd_neigh_list_parsed, /* function to call */
1313 .data = NULL, /* 2nd arg of func */
1314 .help_str = "list all known neighbors",
1315 .tokens = { /* token list, NULL terminated */
1316 (void *)&cmd_neigh_list_cmd,
1317 (void *)&cmd_neigh_list_action,
1322 /*******************/
1324 struct cmd_logfile_result {
1325 cmdline_fixed_string_t logfile;
1326 cmdline_filename_t file;
1329 static void cmd_logfile_parsed(void *parsed_result,
1333 if (xbee_logfile != NULL)
1334 fclose(xbee_logfile);
1335 xbee_logfile = fopen(xbee_logfilename, "a");
1336 if (xbee_logfile == NULL)
1337 printf("cannot open file: %s\n", strerror(errno));
1338 fprintf(xbee_logfile, "-------------------start\n");
1339 printf("enabling log\n");
1342 cmdline_parse_token_string_t cmd_logfile_logfile =
1343 TOKEN_STRING_INITIALIZER(struct cmd_logfile_result, logfile, "logfile");
1345 cmdline_parse_token_file_t cmd_logfile_file =
1346 TOKEN_FILE_INITIALIZER(struct cmd_logfile_result, file,
1347 PARSE_FILE_F_CREATE);
1349 cmdline_parse_inst_t cmd_logfile = {
1350 .f = cmd_logfile_parsed, /* function to call */
1351 .data = NULL, /* 2nd arg of func */
1352 .help_str = "<logfile FILE> set log file",
1353 .tokens = { /* token list, NULL terminated */
1354 (void *)&cmd_logfile_logfile,
1355 (void *)&cmd_logfile_file,
1362 /* this structure is filled when cmd_log is parsed successfully */
1363 struct cmd_log_result {
1364 cmdline_fixed_string_t log;
1365 cmdline_fixed_string_t onoff;
1368 /* function called when cmd_log is parsed successfully */
1369 static void cmd_log_parsed(void *parsed_result, struct cmdline *cl, void *data)
1371 struct cmd_log_result *res = parsed_result;
1372 if (!strcmp(res->onoff, "on") && xbee_logfile == NULL) {
1373 xbee_logfile = fopen(xbee_logfilename, "a");
1374 if (xbee_logfile == NULL)
1375 printf("cannot open file: %s\n", strerror(errno));
1376 fprintf(xbee_logfile, "-------------------start\n");
1378 else if (!strcmp(res->onoff, "off") && xbee_logfile != NULL) {
1379 fclose(xbee_logfile);
1380 xbee_logfile = NULL;
1384 cmdline_parse_token_string_t cmd_log_log =
1385 TOKEN_STRING_INITIALIZER(struct cmd_log_result, log, "log");
1387 cmdline_parse_token_string_t cmd_log_onoff =
1388 TOKEN_STRING_INITIALIZER(struct cmd_log_result, onoff, "on#off");
1390 cmdline_parse_inst_t cmd_log = {
1391 .f = cmd_log_parsed, /* function to call */
1392 .data = NULL, /* 2nd arg of func */
1393 .help_str = "enable/disable hexlog of received packets",
1394 .tokens = { /* token list, NULL terminated */
1395 (void *)&cmd_log_log,
1396 (void *)&cmd_log_onoff,
1402 /*******************/
1404 struct cmd_saveconfig_result {
1405 cmdline_fixed_string_t saveconfig;
1406 cmdline_filename_t file;
1409 static void cmd_saveconfig_parsed(void *parsed_result,
1413 struct cmd_saveconfig_result *res = parsed_result;
1415 if (xbeeapp_dump_config(res->file) < 0)
1416 printf("cannot save config\n");
1419 cmdline_parse_token_string_t cmd_saveconfig_saveconfig =
1420 TOKEN_STRING_INITIALIZER(struct cmd_saveconfig_result, saveconfig,
1423 cmdline_parse_token_file_t cmd_saveconfig_file =
1424 TOKEN_FILE_INITIALIZER(struct cmd_saveconfig_result, file,
1425 PARSE_FILE_F_CREATE);
1427 cmdline_parse_inst_t cmd_saveconfig = {
1428 .f = cmd_saveconfig_parsed, /* function to call */
1429 .data = NULL, /* 2nd arg of func */
1430 .help_str = "<saveconfig FILE> set log file",
1431 .tokens = { /* token list, NULL terminated */
1432 (void *)&cmd_saveconfig_saveconfig,
1433 (void *)&cmd_saveconfig_file,
1438 /*******************/
1440 struct cmd_loadconfig_result {
1441 cmdline_fixed_string_t loadconfig;
1442 cmdline_filename_t file;
1445 static void cmd_loadconfig_parsed(void *parsed_result,
1451 cmdline_parse_token_string_t cmd_loadconfig_loadconfig =
1452 TOKEN_STRING_INITIALIZER(struct cmd_loadconfig_result, loadconfig,
1455 cmdline_parse_token_file_t cmd_loadconfig_file =
1456 TOKEN_FILE_INITIALIZER(struct cmd_loadconfig_result, file,
1457 PARSE_FILE_F_CREATE);
1459 cmdline_parse_inst_t cmd_loadconfig = {
1460 .f = cmd_loadconfig_parsed, /* function to call */
1461 .data = NULL, /* 2nd arg of func */
1462 .help_str = "<loadconfig FILE> set log file",
1463 .tokens = { /* token list, NULL terminated */
1464 (void *)&cmd_loadconfig_loadconfig,
1465 (void *)&cmd_loadconfig_file,
1470 /**********************************************************/
1471 /**********************************************************/
1472 /****** CONTEXT (list of instruction) */
1475 cmdline_parse_ctx_t main_ctx = {
1480 &cmd_monitor_period,
1486 &cmd_range_powermask,
1489 &cmd_rc_send_period,
1490 &cmd_rc_send_dstaddr,