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>
41 #include <cmdline_parse.h>
42 #include <cmdline_parse_num.h>
43 #include <cmdline_parse_string.h>
44 #include <cmdline_parse_file.h>
47 #include "xbee_neighbor.h"
48 #include "xbee_atcmd.h"
49 #include "xbee_stats.h"
51 #include "xbee_proto.h"
53 #include "parse_atcmd.h"
54 #include "parse_neighbor.h"
55 #include "parse_monitor.h"
58 static struct monitor_reg_list monitor_list = LIST_HEAD_INITIALIZER(x/*XXX*/);
59 static int monitor_period_ms = 1000;
60 static int monitor_running = 0;
61 static int monitor_count = 0;
62 static struct event monitor_event;
63 struct monitor_reg *monitor_current;
65 static int range_period_ms = 1000;
66 static int range_powermask = 0x1F;
67 static uint8_t range_power = 0;
68 static int range_running = 0;
69 static uint64_t range_dstaddr = 0xFFFF; /* broadcast by default */
70 static struct event range_event;
71 static int range_count = 100;
72 static int range_cur_count = 0;
74 static const char *xbee_logfilename = "/tmp/xbee.log";
76 static void monitor_cb(int s, short event, void *arg)
79 struct cmdline *cl = arg;
81 if (monitor_current == NULL)
82 monitor_current = LIST_FIRST(&monitor_list);
84 xbeeapp_send_atcmd(monitor_current->atcmd, NULL, 0, 0);
85 monitor_current = LIST_NEXT(monitor_current, next);
87 evtimer_set(&monitor_event, monitor_cb, cl);
89 tv.tv_usec = (1000 * monitor_period_ms) / monitor_count;
90 evtimer_add(&monitor_event, &tv);
93 static void range_cb(int s, short event, void *arg)
96 struct cmdline *cl = arg;
102 /* get new xmit power */
103 for (i = 1; i <= 8; i++) {
104 mask = 1 << ((range_power + i) & 0x7);
105 if (mask & range_powermask)
108 range_power = ((range_power + i) & 0x7);
110 xbeeapp_send_atcmd("PL", &range_power, sizeof(range_power), 0, NULL, NULL);
111 snprintf(buf, sizeof(buf), "range%d", range_power);
112 xbeeapp_send_msg(range_dstaddr, buf, strlen(buf), 0);
114 if (range_cur_count == 0) {
119 evtimer_set(&range_event, range_cb, cl);
121 tv.tv_usec = 1000 * range_period_ms;
122 evtimer_add(&range_event, &tv);
127 /* this structure is filled when cmd_stats is parsed successfully */
128 struct cmd_stats_result {
129 fixed_string_t stats;
130 fixed_string_t action;
133 /* function called when cmd_stats is parsed successfully */
134 static void cmd_stats_parsed(void *parsed_result, struct cmdline *cl, void *data)
136 struct cmd_stats_result *res = parsed_result;
138 if (!strcmp(res->action, "show")) {
139 xbee_dump_stats(stdout, xbee_dev);
140 if (xbee_logfile != NULL)
141 xbee_dump_stats(xbee_logfile, xbee_dev);
143 else if (!strcmp(res->action, "reset"))
144 xbee_reset_stats(xbee_dev);
147 parse_pgm_token_string_t cmd_stats_stats =
148 TOKEN_STRING_INITIALIZER(struct cmd_stats_result, stats, "stats");
149 parse_pgm_token_string_t cmd_stats_action =
150 TOKEN_STRING_INITIALIZER(struct cmd_stats_result, action, "show#reset");
152 parse_pgm_inst_t cmd_stats = {
153 .f = cmd_stats_parsed, /* function to call */
154 .data = NULL, /* 2nd arg of func */
155 .help_str = "Send a stats to the xbee device",
156 .tokens = { /* token list, NULL terminated */
157 (prog_void *)&cmd_stats_stats,
158 (prog_void *)&cmd_stats_action,
165 /* this structure is filled when cmd_monitor is parsed successfully */
166 struct cmd_monitor_result {
167 fixed_string_t monitor;
168 fixed_string_t action;
171 /* function called when cmd_monitor is parsed successfully */
172 static void cmd_monitor_parsed(void *parsed_result, struct cmdline *cl,
175 struct cmd_monitor_result *res = parsed_result;
176 struct monitor_reg *m;
178 if (!strcmp(res->action, "show")) {
179 printf("monitor period is %d ms, %d regs in list\n",
180 monitor_period_ms, monitor_count);
181 LIST_FOREACH(m, &monitor_list, next)
182 printf(" %s\n", m->desc);
184 else if (!strcmp(res->action, "start")) {
186 if (monitor_running) {
187 printf("already running\n");
190 if (monitor_count == 0) {
191 printf("no regs to be monitored\n");
194 evtimer_set(&monitor_event, monitor_cb, cl);
197 evtimer_add(&monitor_event, &tv);
199 monitor_current = LIST_FIRST(&monitor_list);
201 else if (!strcmp(res->action, "end")) {
202 if (monitor_running == 0) {
203 printf("not running\n");
207 evtimer_del(&monitor_event);
211 parse_pgm_token_string_t cmd_monitor_monitor =
212 TOKEN_STRING_INITIALIZER(struct cmd_monitor_result, monitor, "monitor");
213 parse_pgm_token_string_t cmd_monitor_action =
214 TOKEN_STRING_INITIALIZER(struct cmd_monitor_result, action,
217 parse_pgm_inst_t cmd_monitor = {
218 .f = cmd_monitor_parsed, /* function to call */
219 .data = NULL, /* 2nd arg of func */
220 .help_str = "start/stop/show current monitoring",
221 .tokens = { /* token list, NULL terminated */
222 (prog_void *)&cmd_monitor_monitor,
223 (prog_void *)&cmd_monitor_action,
230 /* this structure is filled when cmd_monitor_add is parsed successfully */
231 struct cmd_monitor_add_result {
232 fixed_string_t monitor;
233 fixed_string_t action;
234 struct xbee_atcmd *cmd;
237 /* function called when cmd_monitor_add is parsed successfully */
238 static void cmd_monitor_add_parsed(void *parsed_result, struct cmdline *cl,
241 struct cmd_monitor_add_result *res = parsed_result;
242 struct monitor_reg *m;
244 LIST_FOREACH(m, &monitor_list, next) {
245 if (!strcmp(m->desc, res->cmd->desc))
250 printf("already exist\n");
254 m = malloc(sizeof(*m));
260 m->desc = res->cmd->desc;
261 m->atcmd = res->cmd->name;
262 LIST_INSERT_HEAD(&monitor_list, m, next);
266 parse_pgm_token_string_t cmd_monitor_add_monitor_add =
267 TOKEN_STRING_INITIALIZER(struct cmd_monitor_add_result, monitor,
269 parse_pgm_token_string_t cmd_monitor_add_action =
270 TOKEN_STRING_INITIALIZER(struct cmd_monitor_add_result, action,
272 parse_pgm_token_atcmd_t cmd_monitor_add_atcmd =
273 TOKEN_ATCMD_INITIALIZER(struct cmd_monitor_add_result, cmd, &xbee_dev,
274 XBEE_ATCMD_F_READ, XBEE_ATCMD_F_READ);
277 parse_pgm_inst_t cmd_monitor_add = {
278 .f = cmd_monitor_add_parsed, /* function to call */
279 .data = NULL, /* 2nd arg of func */
280 .help_str = "add a register in monitor list",
281 .tokens = { /* token list, NULL terminated */
282 (prog_void *)&cmd_monitor_add_monitor_add,
283 (prog_void *)&cmd_monitor_add_action,
284 (prog_void *)&cmd_monitor_add_atcmd,
291 /* this structure is filled when cmd_monitor_period is parsed successfully */
292 struct cmd_monitor_period_result {
293 fixed_string_t monitor;
294 fixed_string_t action;
298 /* function called when cmd_monitor_period is parsed successfully */
299 static void cmd_monitor_period_parsed(void *parsed_result, struct cmdline *cl,
302 struct cmd_monitor_period_result *res = parsed_result;
304 if (res->period < 100) {
305 printf("error, minimum period is 100 ms\n");
309 monitor_period_ms = res->period;
312 parse_pgm_token_string_t cmd_monitor_period_monitor_period =
313 TOKEN_STRING_INITIALIZER(struct cmd_monitor_period_result, monitor,
315 parse_pgm_token_string_t cmd_monitor_period_action =
316 TOKEN_STRING_INITIALIZER(struct cmd_monitor_period_result, action,
318 parse_pgm_token_num_t cmd_monitor_period_period =
319 TOKEN_NUM_INITIALIZER(struct cmd_monitor_period_result, period, UINT32);
322 parse_pgm_inst_t cmd_monitor_period = {
323 .f = cmd_monitor_period_parsed, /* function to call */
324 .data = NULL, /* 2nd arg of func */
325 .help_str = "set register monitoring period",
326 .tokens = { /* token list, NULL terminated */
327 (prog_void *)&cmd_monitor_period_monitor_period,
328 (prog_void *)&cmd_monitor_period_action,
329 (prog_void *)&cmd_monitor_period_period,
336 /* this structure is filled when cmd_monitor_del is parsed successfully */
337 struct cmd_monitor_del_result {
338 fixed_string_t monitor;
339 fixed_string_t action;
340 struct monitor_reg *m;
343 /* function called when cmd_monitor_del is parsed successfully */
344 static void cmd_monitor_del_parsed(void *parsed_result, struct cmdline *cl,
347 struct cmd_monitor_del_result *res = parsed_result;
349 monitor_current = LIST_NEXT(res->m, next);
350 LIST_REMOVE(res->m, next);
353 if (monitor_count == 0) {
354 printf("Disable monitoring, no more event\n");
355 evtimer_del(&monitor_event);
361 parse_pgm_token_string_t cmd_monitor_del_monitor_del =
362 TOKEN_STRING_INITIALIZER(struct cmd_monitor_del_result, monitor,
364 parse_pgm_token_string_t cmd_monitor_del_action =
365 TOKEN_STRING_INITIALIZER(struct cmd_monitor_del_result, action,
367 parse_pgm_token_monitor_t cmd_monitor_del_atcmd =
368 TOKEN_MONITOR_INITIALIZER(struct cmd_monitor_del_result, m,
372 parse_pgm_inst_t cmd_monitor_del = {
373 .f = cmd_monitor_del_parsed, /* function to call */
374 .data = NULL, /* 2nd arg of func */
375 .help_str = "del a register in monitor list",
376 .tokens = { /* token list, NULL terminated */
377 (prog_void *)&cmd_monitor_del_monitor_del,
378 (prog_void *)&cmd_monitor_del_action,
379 (prog_void *)&cmd_monitor_del_atcmd,
386 /* this structure is filled when cmd_range is parsed successfully */
387 struct cmd_range_result {
388 fixed_string_t range;
389 fixed_string_t action;
392 /* function called when cmd_range is parsed successfully */
393 static void cmd_range_parsed(void *parsed_result, struct cmdline *cl,
396 struct cmd_range_result *res = parsed_result;
398 if (!strcmp(res->action, "show")) {
399 printf("range infos:\n");
400 printf(" range period %d\n", range_period_ms);
401 printf(" range count %d\n", range_count);
402 printf(" range powermask 0x%x\n", range_powermask);
403 printf(" range dstaddr %"PRIx64"\n", range_dstaddr);
405 printf(" range test is running\n");
407 printf(" range test is not running\n");
409 else if (!strcmp(res->action, "start")) {
412 printf("already running\n");
415 range_cur_count = range_count;
416 evtimer_set(&range_event, range_cb, cl);
419 evtimer_add(&range_event, &tv);
422 else if (!strcmp(res->action, "end")) {
423 if (range_running == 0) {
424 printf("not running\n");
428 evtimer_del(&range_event);
432 parse_pgm_token_string_t cmd_range_range =
433 TOKEN_STRING_INITIALIZER(struct cmd_range_result, range, "range");
434 parse_pgm_token_string_t cmd_range_action =
435 TOKEN_STRING_INITIALIZER(struct cmd_range_result, action,
438 parse_pgm_inst_t cmd_range = {
439 .f = cmd_range_parsed, /* function to call */
440 .data = NULL, /* 2nd arg of func */
441 .help_str = "start/stop/show current rangeing",
442 .tokens = { /* token list, NULL terminated */
443 (prog_void *)&cmd_range_range,
444 (prog_void *)&cmd_range_action,
451 /* this structure is filled when cmd_range_period is parsed successfully */
452 struct cmd_range_period_result {
453 fixed_string_t range;
454 fixed_string_t action;
458 /* function called when cmd_range_period is parsed successfully */
459 static void cmd_range_period_parsed(void *parsed_result, struct cmdline *cl,
462 struct cmd_range_period_result *res = parsed_result;
464 if (res->period < 10) {
465 printf("error, minimum period is 10 ms\n");
469 range_period_ms = res->period;
472 parse_pgm_token_string_t cmd_range_period_range_period =
473 TOKEN_STRING_INITIALIZER(struct cmd_range_period_result, range,
475 parse_pgm_token_string_t cmd_range_period_action =
476 TOKEN_STRING_INITIALIZER(struct cmd_range_period_result, action,
478 parse_pgm_token_num_t cmd_range_period_period =
479 TOKEN_NUM_INITIALIZER(struct cmd_range_period_result, period, UINT32);
482 parse_pgm_inst_t cmd_range_period = {
483 .f = cmd_range_period_parsed, /* function to call */
484 .data = NULL, /* 2nd arg of func */
485 .help_str = "set range test period",
486 .tokens = { /* token list, NULL terminated */
487 (prog_void *)&cmd_range_period_range_period,
488 (prog_void *)&cmd_range_period_action,
489 (prog_void *)&cmd_range_period_period,
496 /* this structure is filled when cmd_range_count is parsed successfully */
497 struct cmd_range_count_result {
498 fixed_string_t range;
499 fixed_string_t action;
503 /* function called when cmd_range_count is parsed successfully */
504 static void cmd_range_count_parsed(void *parsed_result, struct cmdline *cl,
507 struct cmd_range_count_result *res = parsed_result;
508 range_count = res->count;
511 parse_pgm_token_string_t cmd_range_count_range_count =
512 TOKEN_STRING_INITIALIZER(struct cmd_range_count_result, range,
514 parse_pgm_token_string_t cmd_range_count_action =
515 TOKEN_STRING_INITIALIZER(struct cmd_range_count_result, action,
517 parse_pgm_token_num_t cmd_range_count_count =
518 TOKEN_NUM_INITIALIZER(struct cmd_range_count_result, count, UINT32);
521 parse_pgm_inst_t cmd_range_count = {
522 .f = cmd_range_count_parsed, /* function to call */
523 .data = NULL, /* 2nd arg of func */
524 .help_str = "set range test count",
525 .tokens = { /* token list, NULL terminated */
526 (prog_void *)&cmd_range_count_range_count,
527 (prog_void *)&cmd_range_count_action,
528 (prog_void *)&cmd_range_count_count,
535 /* this structure is filled when cmd_range_powermask is parsed successfully */
536 struct cmd_range_powermask_result {
537 fixed_string_t range;
538 fixed_string_t action;
542 /* function called when cmd_range_powermask is parsed successfully */
543 static void cmd_range_powermask_parsed(void *parsed_result, struct cmdline *cl,
546 struct cmd_range_powermask_result *res = parsed_result;
547 range_powermask = res->powermask;
550 parse_pgm_token_string_t cmd_range_powermask_range_powermask =
551 TOKEN_STRING_INITIALIZER(struct cmd_range_powermask_result, range,
553 parse_pgm_token_string_t cmd_range_powermask_action =
554 TOKEN_STRING_INITIALIZER(struct cmd_range_powermask_result, action,
556 parse_pgm_token_num_t cmd_range_powermask_powermask =
557 TOKEN_NUM_INITIALIZER(struct cmd_range_powermask_result, powermask,
561 parse_pgm_inst_t cmd_range_powermask = {
562 .f = cmd_range_powermask_parsed, /* function to call */
563 .data = NULL, /* 2nd arg of func */
564 .help_str = "set range test powermask",
565 .tokens = { /* token list, NULL terminated */
566 (prog_void *)&cmd_range_powermask_range_powermask,
567 (prog_void *)&cmd_range_powermask_action,
568 (prog_void *)&cmd_range_powermask_powermask,
575 /* this structure is filled when cmd_range_dstaddr is parsed successfully */
576 struct cmd_range_dstaddr_result {
577 fixed_string_t range;
578 fixed_string_t action;
582 /* function called when cmd_range_dstaddr is parsed successfully */
583 static void cmd_range_dstaddr_parsed(void *parsed_result, struct cmdline *cl,
586 struct cmd_range_dstaddr_result *res = parsed_result;
588 range_dstaddr = res->dstaddr;
591 parse_pgm_token_string_t cmd_range_dstaddr_range_dstaddr =
592 TOKEN_STRING_INITIALIZER(struct cmd_range_dstaddr_result, range,
594 parse_pgm_token_string_t cmd_range_dstaddr_action =
595 TOKEN_STRING_INITIALIZER(struct cmd_range_dstaddr_result, action,
597 parse_pgm_token_num_t cmd_range_dstaddr_dstaddr =
598 TOKEN_NUM_INITIALIZER(struct cmd_range_dstaddr_result, dstaddr, UINT64);
601 parse_pgm_inst_t cmd_range_dstaddr = {
602 .f = cmd_range_dstaddr_parsed, /* function to call */
603 .data = NULL, /* 2nd arg of func */
604 .help_str = "set register rangeing dstaddr",
605 .tokens = { /* token list, NULL terminated */
606 (prog_void *)&cmd_range_dstaddr_range_dstaddr,
607 (prog_void *)&cmd_range_dstaddr_action,
608 (prog_void *)&cmd_range_dstaddr_dstaddr,
615 /* this structure is filled when cmd_ping is parsed successfully */
616 struct cmd_ping_result {
620 /* function called when cmd_ping is parsed successfully */
621 static void cmd_ping_parsed(void *parsed_result, struct cmdline *cl, void *data)
623 xbeeapp_send_atcmd("VL", NULL, 0, 1, NULL, NULL);
626 parse_pgm_token_string_t cmd_ping_ping =
627 TOKEN_STRING_INITIALIZER(struct cmd_ping_result, ping, "ping");
629 parse_pgm_inst_t cmd_ping = {
630 .f = cmd_ping_parsed, /* function to call */
631 .data = NULL, /* 2nd arg of func */
632 .help_str = "Send a ping to the xbee device",
633 .tokens = { /* token list, NULL terminated */
634 (prog_void *)&cmd_ping_ping,
641 /* this structure is filled when cmd_raw is parsed successfully */
642 struct cmd_raw_result {
646 /* function called when cmd_raw is parsed successfully */
647 static void cmd_raw_parsed(void *parsed_result, struct cmdline *cl, void *data)
649 printf("switched to raw mode, CTRL-D to exit\n");
650 rdline_stop(&cl->rdl); /* don't display prompt when return */
654 parse_pgm_token_string_t cmd_raw_raw =
655 TOKEN_STRING_INITIALIZER(struct cmd_raw_result, raw, "raw");
657 parse_pgm_inst_t cmd_raw = {
658 .f = cmd_raw_parsed, /* function to call */
659 .data = NULL, /* 2nd arg of func */
660 .help_str = "Switch to raw mode",
661 .tokens = { /* token list, NULL terminated */
662 (prog_void *)&cmd_raw_raw,
669 /* this structure is filled when cmd_dump is parsed successfully */
670 struct cmd_dump_result {
672 fixed_string_t onoff;
675 /* function called when cmd_dump is parsed successfully */
676 static void cmd_dump_parsed(void *parsed_result, struct cmdline *cl, void *data)
678 struct cmd_dump_result *res = parsed_result;
679 if (!strcmp(res->onoff, "on"))
685 parse_pgm_token_string_t cmd_dump_dump =
686 TOKEN_STRING_INITIALIZER(struct cmd_dump_result, dump, "dump");
688 parse_pgm_token_string_t cmd_dump_onoff =
689 TOKEN_STRING_INITIALIZER(struct cmd_dump_result, onoff, "on#off");
691 parse_pgm_inst_t cmd_dump = {
692 .f = cmd_dump_parsed, /* function to call */
693 .data = NULL, /* 2nd arg of func */
694 .help_str = "enable/disable hexdump of received packets",
695 .tokens = { /* token list, NULL terminated */
696 (prog_void *)&cmd_dump_dump,
697 (prog_void *)&cmd_dump_onoff,
704 /* this structure is filled when cmd_debug is parsed successfully */
705 struct cmd_debug_result {
706 fixed_string_t debug;
707 fixed_string_t onoff;
710 /* function called when cmd_debug is parsed successfully */
711 static void cmd_debug_parsed(void *parsed_result, struct cmdline *cl, void *data)
713 struct cmd_debug_result *res = parsed_result;
714 if (!strcmp(res->onoff, "on"))
720 parse_pgm_token_string_t cmd_debug_debug =
721 TOKEN_STRING_INITIALIZER(struct cmd_debug_result, debug, "debug");
723 parse_pgm_token_string_t cmd_debug_onoff =
724 TOKEN_STRING_INITIALIZER(struct cmd_debug_result, onoff, "on#off");
726 parse_pgm_inst_t cmd_debug = {
727 .f = cmd_debug_parsed, /* function to call */
728 .data = NULL, /* 2nd arg of func */
729 .help_str = "enable/disable additionnal debug",
730 .tokens = { /* token list, NULL terminated */
731 (prog_void *)&cmd_debug_debug,
732 (prog_void *)&cmd_debug_onoff,
739 /* this structure is filled when cmd_help is parsed successfully */
740 struct cmd_help_result {
742 struct xbee_atcmd *cmd;
745 /* function called when cmd_help is parsed successfully */
746 static void cmd_help_parsed(void *parsed_result, struct cmdline *cl,
749 struct cmd_help_result *res = parsed_result;
752 type = (res->cmd->flags & (XBEE_ATCMD_F_READ | XBEE_ATCMD_F_WRITE));
754 case XBEE_ATCMD_F_READ:
755 printf("Read-only\n");
757 case XBEE_ATCMD_F_WRITE:
758 printf("Write-only\n");
761 printf("Read-write\n");
764 if (res->cmd->flags & XBEE_ATCMD_F_PARAM_NONE)
765 printf("No argument\n");
766 else if (res->cmd->flags & XBEE_ATCMD_F_PARAM_U8)
767 printf("Register is unsigned 8 bits\n");
768 else if (res->cmd->flags & XBEE_ATCMD_F_PARAM_U16)
769 printf("Register is unsigned 16 bits\n");
770 else if (res->cmd->flags & XBEE_ATCMD_F_PARAM_U32)
771 printf("Register is unsigned 32 bits\n");
772 else if (res->cmd->flags & XBEE_ATCMD_F_PARAM_S16)
773 printf("Register is signed 16 bits\n");
774 else if (res->cmd->flags & XBEE_ATCMD_F_PARAM_STRING_20B)
775 printf("Register is a 20 bytes string\n");
777 printf("Unknown argument\n");
779 printf("%s\n", res->cmd->help);
782 parse_pgm_token_string_t cmd_help_help =
783 TOKEN_STRING_INITIALIZER(struct cmd_help_result, help, "help");
785 parse_pgm_token_atcmd_t cmd_help_atcmd =
786 TOKEN_ATCMD_INITIALIZER(struct cmd_help_result, cmd, &xbee_dev,
789 parse_pgm_inst_t cmd_help = {
790 .f = cmd_help_parsed, /* function to call */
791 .data = NULL, /* 2nd arg of func */
792 .help_str = "Help a register using an AT command",
793 .tokens = { /* token list, NULL terminated */
794 (prog_void *)&cmd_help_help,
795 (prog_void *)&cmd_help_atcmd,
802 /* this structure is filled when cmd_read is parsed successfully */
803 struct cmd_read_result {
805 struct xbee_atcmd *cmd;
808 /* function called when cmd_read is parsed successfully */
809 static void cmd_read_parsed(void *parsed_result, struct cmdline *cl,
812 struct cmd_read_result *res = parsed_result;
813 xbeeapp_send_atcmd(res->cmd->name, NULL, 0, 1, NULL, NULL);
816 parse_pgm_token_string_t cmd_read_read =
817 TOKEN_STRING_INITIALIZER(struct cmd_read_result, read, "read");
819 parse_pgm_token_atcmd_t cmd_read_atcmd =
820 TOKEN_ATCMD_INITIALIZER(struct cmd_read_result, cmd, &xbee_dev,
821 XBEE_ATCMD_F_READ, XBEE_ATCMD_F_READ);
823 parse_pgm_inst_t cmd_read = {
824 .f = cmd_read_parsed, /* function to call */
825 .data = NULL, /* 2nd arg of func */
826 .help_str = "Read a register using an AT command",
827 .tokens = { /* token list, NULL terminated */
828 (prog_void *)&cmd_read_read,
829 (prog_void *)&cmd_read_atcmd,
836 /* this structure is filled when cmd_write is parsed successfully */
837 struct cmd_write_result {
838 fixed_string_t write;
839 struct xbee_atcmd *cmd;
847 /* function called when cmd_write is parsed successfully */
848 static void cmd_write_parsed(void *parsed_result, struct cmdline *cl,
851 struct cmd_write_result *res = parsed_result;
855 if (res->cmd->flags & XBEE_ATCMD_F_PARAM_NONE) {
859 else if (res->cmd->flags & XBEE_ATCMD_F_PARAM_U8) {
860 len = sizeof(res->u8);
863 else if (res->cmd->flags & XBEE_ATCMD_F_PARAM_U16) {
864 len = sizeof(res->u16);
865 res->u16 = htons(res->u16);
868 else if (res->cmd->flags & XBEE_ATCMD_F_PARAM_U32) {
869 len = sizeof(res->u32);
870 res->u32 = htonl(res->u32);
874 printf("Unknown argument type\n");
877 xbeeapp_send_atcmd(res->cmd->name, param, len, 1, NULL, NULL);
880 parse_pgm_token_string_t cmd_write_write =
881 TOKEN_STRING_INITIALIZER(struct cmd_write_result, write,
884 parse_pgm_token_atcmd_t cmd_write_none_atcmd =
885 TOKEN_ATCMD_INITIALIZER(struct cmd_write_result, cmd,
887 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_NONE,
888 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_NONE);
890 parse_pgm_inst_t cmd_write_none = {
891 .f = cmd_write_parsed, /* function to call */
892 .data = NULL, /* 2nd arg of func */
893 .help_str = "Send an AT command (no argument)",
894 .tokens = { /* token list, NULL terminated */
895 (prog_void *)&cmd_write_write,
896 (prog_void *)&cmd_write_none_atcmd,
901 parse_pgm_token_atcmd_t cmd_write_u8_atcmd =
902 TOKEN_ATCMD_INITIALIZER(struct cmd_write_result, cmd,
904 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U8,
905 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U8);
907 parse_pgm_token_num_t cmd_write_u8_u8 =
908 TOKEN_NUM_INITIALIZER(struct cmd_write_result, u8, UINT8);
910 parse_pgm_inst_t cmd_write_u8 = {
911 .f = cmd_write_parsed, /* function to call */
912 .data = NULL, /* 2nd arg of func */
913 .help_str = "Write a 8 bits register using an AT command",
914 .tokens = { /* token list, NULL terminated */
915 (prog_void *)&cmd_write_write,
916 (prog_void *)&cmd_write_u8_atcmd,
917 (prog_void *)&cmd_write_u8_u8,
922 parse_pgm_token_atcmd_t cmd_write_u16_atcmd =
923 TOKEN_ATCMD_INITIALIZER(struct cmd_write_result, cmd,
925 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U16,
926 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U16);
928 parse_pgm_token_num_t cmd_write_u16_u16 =
929 TOKEN_NUM_INITIALIZER(struct cmd_write_result, u16, UINT16);
931 parse_pgm_inst_t cmd_write_u16 = {
932 .f = cmd_write_parsed, /* function to call */
933 .data = NULL, /* 2nd arg of func */
934 .help_str = "Write a 16 bits register using an AT command",
935 .tokens = { /* token list, NULL terminated */
936 (prog_void *)&cmd_write_write,
937 (prog_void *)&cmd_write_u16_atcmd,
938 (prog_void *)&cmd_write_u16_u16,
943 parse_pgm_token_atcmd_t cmd_write_u32_atcmd =
944 TOKEN_ATCMD_INITIALIZER(struct cmd_write_result, cmd,
946 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U32,
947 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U32);
949 parse_pgm_token_num_t cmd_write_u32_u32 =
950 TOKEN_NUM_INITIALIZER(struct cmd_write_result, u32, UINT32);
952 parse_pgm_inst_t cmd_write_u32 = {
953 .f = cmd_write_parsed, /* function to call */
954 .data = NULL, /* 2nd arg of func */
955 .help_str = "Write a 32 bits register using an AT command",
956 .tokens = { /* token list, NULL terminated */
957 (prog_void *)&cmd_write_write,
958 (prog_void *)&cmd_write_u32_atcmd,
959 (prog_void *)&cmd_write_u32_u32,
966 /* this structure is filled when cmd_sendmsg is parsed successfully */
967 struct cmd_sendmsg_result {
968 fixed_string_t sendmsg;
973 /* function called when cmd_sendmsg is parsed successfully */
974 static void cmd_sendmsg_parsed(void *parsed_result, struct cmdline *cl,
977 struct cmd_sendmsg_result *res = parsed_result;
978 xbeeapp_send_msg(res->addr, res->data, strlen(res->data), 1);
981 parse_pgm_token_string_t cmd_sendmsg_sendmsg =
982 TOKEN_STRING_INITIALIZER(struct cmd_sendmsg_result, sendmsg, "sendmsg");
984 parse_pgm_token_num_t cmd_sendmsg_addr =
985 TOKEN_NUM_INITIALIZER(struct cmd_sendmsg_result, addr, UINT64);
987 parse_pgm_token_string_t cmd_sendmsg_data =
988 TOKEN_STRING_INITIALIZER(struct cmd_sendmsg_result, data, NULL);
990 parse_pgm_inst_t cmd_sendmsg = {
991 .f = cmd_sendmsg_parsed, /* function to call */
992 .data = NULL, /* 2nd arg of func */
993 .help_str = "Send data to a node using its address",
994 .tokens = { /* token list, NULL terminated */
995 (prog_void *)&cmd_sendmsg_sendmsg,
996 (prog_void *)&cmd_sendmsg_addr,
997 (prog_void *)&cmd_sendmsg_data,
1004 /* this structure is filled when cmd_sendmsg_name is parsed successfully */
1005 struct cmd_sendmsg_name_result {
1006 fixed_string_t sendmsg_name;
1007 struct xbee_neigh *neigh;
1008 fixed_string_t data;
1011 /* function called when cmd_sendmsg_name is parsed successfully */
1012 static void cmd_sendmsg_name_parsed(void *parsed_result, struct cmdline *cl,
1015 struct cmd_sendmsg_name_result *res = parsed_result;
1016 xbeeapp_send_msg(res->neigh->addr, res->data, strlen(res->data), 1);
1019 parse_pgm_token_string_t cmd_sendmsg_name_sendmsg_name =
1020 TOKEN_STRING_INITIALIZER(struct cmd_sendmsg_name_result, sendmsg_name,
1023 parse_pgm_token_neighbor_t cmd_sendmsg_name_neigh =
1024 TOKEN_NEIGHBOR_INITIALIZER(struct cmd_sendmsg_name_result, neigh,
1027 parse_pgm_token_string_t cmd_sendmsg_name_data =
1028 TOKEN_STRING_INITIALIZER(struct cmd_sendmsg_name_result, data, NULL);
1030 parse_pgm_inst_t cmd_sendmsg_name = {
1031 .f = cmd_sendmsg_name_parsed, /* function to call */
1032 .data = NULL, /* 2nd arg of func */
1033 .help_str = "Send data to a node using its name",
1034 .tokens = { /* token list, NULL terminated */
1035 (prog_void *)&cmd_sendmsg_name_sendmsg_name,
1036 (prog_void *)&cmd_sendmsg_name_neigh,
1037 (prog_void *)&cmd_sendmsg_name_data,
1044 struct cmd_neigh_del_result {
1046 fixed_string_t action;
1047 struct xbee_neigh *neigh;
1050 static void cmd_neigh_del_parsed(void *parsed_result,
1054 struct cmd_neigh_del_result *res = parsed_result;
1055 xbee_neigh_del(xbee_dev, res->neigh);
1058 parse_pgm_token_string_t cmd_neigh_del_cmd =
1059 TOKEN_STRING_INITIALIZER(struct cmd_neigh_del_result, cmd, "neigh");
1060 parse_pgm_token_string_t cmd_neigh_del_action =
1061 TOKEN_STRING_INITIALIZER(struct cmd_neigh_del_result, action, "del");
1062 parse_pgm_token_neighbor_t cmd_neigh_del_neigh =
1063 TOKEN_NEIGHBOR_INITIALIZER(struct cmd_neigh_del_result, neigh,
1066 parse_pgm_inst_t cmd_neigh_del = {
1067 .f = cmd_neigh_del_parsed, /* function to call */
1068 .data = NULL, /* 2nd arg of func */
1069 .help_str = "delete a neighbor",
1070 .tokens = { /* token list, NULL terminated */
1071 (prog_void *)&cmd_neigh_del_cmd,
1072 (prog_void *)&cmd_neigh_del_action,
1073 (prog_void *)&cmd_neigh_del_neigh,
1080 struct cmd_neigh_add_result {
1082 fixed_string_t action;
1083 fixed_string_t name;
1087 static void cmd_neigh_add_parsed(void *parsed_result,
1091 struct cmd_neigh_add_result *res = parsed_result;
1092 if (xbee_neigh_add(xbee_dev, res->name, res->addr) == NULL)
1093 printf("name or addr already exist\n");
1096 parse_pgm_token_string_t cmd_neigh_add_cmd =
1097 TOKEN_STRING_INITIALIZER(struct cmd_neigh_add_result, cmd, "neigh");
1098 parse_pgm_token_string_t cmd_neigh_add_action =
1099 TOKEN_STRING_INITIALIZER(struct cmd_neigh_add_result, action, "add");
1100 parse_pgm_token_string_t cmd_neigh_add_name =
1101 TOKEN_STRING_INITIALIZER(struct cmd_neigh_add_result, name, NULL);
1102 parse_pgm_token_num_t cmd_neigh_add_addr =
1103 TOKEN_NUM_INITIALIZER(struct cmd_neigh_add_result, addr, UINT64);
1105 parse_pgm_inst_t cmd_neigh_add = {
1106 .f = cmd_neigh_add_parsed, /* function to call */
1107 .data = NULL, /* 2nd arg of func */
1108 .help_str = "add a neighbor",
1109 .tokens = { /* token list, NULL terminated */
1110 (prog_void *)&cmd_neigh_add_cmd,
1111 (prog_void *)&cmd_neigh_add_action,
1112 (prog_void *)&cmd_neigh_add_name,
1113 (prog_void *)&cmd_neigh_add_addr,
1120 struct cmd_neigh_list_result {
1122 fixed_string_t action;
1125 static void cmd_neigh_list_parsed(void *parsed_result,
1129 struct xbee_neigh *neigh;
1131 LIST_FOREACH(neigh, &xbee_dev->neigh_list, next) {
1132 printf(" %s: 0x%"PRIx64"\n", neigh->name, neigh->addr);
1136 parse_pgm_token_string_t cmd_neigh_list_cmd =
1137 TOKEN_STRING_INITIALIZER(struct cmd_neigh_list_result, cmd, "neigh");
1138 parse_pgm_token_string_t cmd_neigh_list_action =
1139 TOKEN_STRING_INITIALIZER(struct cmd_neigh_list_result, action, "list");
1141 parse_pgm_inst_t cmd_neigh_list = {
1142 .f = cmd_neigh_list_parsed, /* function to call */
1143 .data = NULL, /* 2nd arg of func */
1144 .help_str = "list all known neighbors",
1145 .tokens = { /* token list, NULL terminated */
1146 (prog_void *)&cmd_neigh_list_cmd,
1147 (prog_void *)&cmd_neigh_list_action,
1152 /*******************/
1154 struct cmd_logfile_result {
1155 fixed_string_t logfile;
1159 static void cmd_logfile_parsed(void *parsed_result,
1163 if (xbee_logfile != NULL)
1164 fclose(xbee_logfile);
1165 xbee_logfile = fopen(xbee_logfilename, "a");
1166 if (xbee_logfile == NULL)
1167 printf("cannot open file: %s\n", strerror(errno));
1168 fprintf(xbee_logfile, "-------------------start\n");
1169 printf("enabling log\n");
1172 parse_pgm_token_string_t cmd_logfile_logfile =
1173 TOKEN_STRING_INITIALIZER(struct cmd_logfile_result, logfile, "logfile");
1175 parse_pgm_token_file_t cmd_logfile_file =
1176 TOKEN_FILE_INITIALIZER(struct cmd_logfile_result, file,
1177 PARSE_FILE_F_CREATE);
1179 parse_pgm_inst_t cmd_logfile = {
1180 .f = cmd_logfile_parsed, /* function to call */
1181 .data = NULL, /* 2nd arg of func */
1182 .help_str = "<logfile FILE> set log file",
1183 .tokens = { /* token list, NULL terminated */
1184 (prog_void *)&cmd_logfile_logfile,
1185 (prog_void *)&cmd_logfile_file,
1192 /* this structure is filled when cmd_log is parsed successfully */
1193 struct cmd_log_result {
1195 fixed_string_t onoff;
1198 /* function called when cmd_log is parsed successfully */
1199 static void cmd_log_parsed(void *parsed_result, struct cmdline *cl, void *data)
1201 struct cmd_log_result *res = parsed_result;
1202 if (!strcmp(res->onoff, "on") && xbee_logfile == NULL) {
1203 xbee_logfile = fopen(xbee_logfilename, "a");
1204 if (xbee_logfile == NULL)
1205 printf("cannot open file: %s\n", strerror(errno));
1206 fprintf(xbee_logfile, "-------------------start\n");
1208 else if (!strcmp(res->onoff, "off") && xbee_logfile != NULL) {
1209 fclose(xbee_logfile);
1210 xbee_logfile = NULL;
1214 parse_pgm_token_string_t cmd_log_log =
1215 TOKEN_STRING_INITIALIZER(struct cmd_log_result, log, "log");
1217 parse_pgm_token_string_t cmd_log_onoff =
1218 TOKEN_STRING_INITIALIZER(struct cmd_log_result, onoff, "on#off");
1220 parse_pgm_inst_t cmd_log = {
1221 .f = cmd_log_parsed, /* function to call */
1222 .data = NULL, /* 2nd arg of func */
1223 .help_str = "enable/disable hexlog of received packets",
1224 .tokens = { /* token list, NULL terminated */
1225 (prog_void *)&cmd_log_log,
1226 (prog_void *)&cmd_log_onoff,
1232 /*******************/
1234 struct cmd_saveconfig_result {
1235 fixed_string_t saveconfig;
1239 static void cmd_saveconfig_parsed(void *parsed_result,
1243 struct cmd_saveconfig_result *res = parsed_result;
1245 if (xbeeapp_dump_config(res->file) < 0)
1246 printf("cannot save config\n");
1249 parse_pgm_token_string_t cmd_saveconfig_saveconfig =
1250 TOKEN_STRING_INITIALIZER(struct cmd_saveconfig_result, saveconfig,
1253 parse_pgm_token_file_t cmd_saveconfig_file =
1254 TOKEN_FILE_INITIALIZER(struct cmd_saveconfig_result, file,
1255 PARSE_FILE_F_CREATE);
1257 parse_pgm_inst_t cmd_saveconfig = {
1258 .f = cmd_saveconfig_parsed, /* function to call */
1259 .data = NULL, /* 2nd arg of func */
1260 .help_str = "<saveconfig FILE> set log file",
1261 .tokens = { /* token list, NULL terminated */
1262 (prog_void *)&cmd_saveconfig_saveconfig,
1263 (prog_void *)&cmd_saveconfig_file,
1268 /*******************/
1270 struct cmd_loadconfig_result {
1271 fixed_string_t loadconfig;
1275 static void cmd_loadconfig_parsed(void *parsed_result,
1281 parse_pgm_token_string_t cmd_loadconfig_loadconfig =
1282 TOKEN_STRING_INITIALIZER(struct cmd_loadconfig_result, loadconfig,
1285 parse_pgm_token_file_t cmd_loadconfig_file =
1286 TOKEN_FILE_INITIALIZER(struct cmd_loadconfig_result, file,
1287 PARSE_FILE_F_CREATE);
1289 parse_pgm_inst_t cmd_loadconfig = {
1290 .f = cmd_loadconfig_parsed, /* function to call */
1291 .data = NULL, /* 2nd arg of func */
1292 .help_str = "<loadconfig FILE> set log file",
1293 .tokens = { /* token list, NULL terminated */
1294 (prog_void *)&cmd_loadconfig_loadconfig,
1295 (prog_void *)&cmd_loadconfig_file,
1300 /**********************************************************/
1301 /**********************************************************/
1302 /****** CONTEXT (list of instruction) */
1305 parse_ctx_t main_ctx = {
1308 (parse_pgm_inst_t *)&cmd_stats,
1309 (parse_pgm_inst_t *)&cmd_monitor,
1310 (parse_pgm_inst_t *)&cmd_monitor_period,
1311 (parse_pgm_inst_t *)&cmd_monitor_add,
1312 (parse_pgm_inst_t *)&cmd_monitor_del,
1313 (parse_pgm_inst_t *)&cmd_range,
1314 (parse_pgm_inst_t *)&cmd_range_period,
1315 (parse_pgm_inst_t *)&cmd_range_count,
1316 (parse_pgm_inst_t *)&cmd_range_powermask,
1317 (parse_pgm_inst_t *)&cmd_range_dstaddr,
1318 (parse_pgm_inst_t *)&cmd_ping,
1319 (parse_pgm_inst_t *)&cmd_raw,
1320 (parse_pgm_inst_t *)&cmd_dump,
1321 (parse_pgm_inst_t *)&cmd_debug,
1322 (parse_pgm_inst_t *)&cmd_help,
1323 (parse_pgm_inst_t *)&cmd_read,
1324 (parse_pgm_inst_t *)&cmd_write_none,
1325 (parse_pgm_inst_t *)&cmd_write_u8,
1326 (parse_pgm_inst_t *)&cmd_write_u16,
1327 (parse_pgm_inst_t *)&cmd_write_u32,
1328 (parse_pgm_inst_t *)&cmd_sendmsg,
1329 (parse_pgm_inst_t *)&cmd_sendmsg_name,
1330 (parse_pgm_inst_t *)&cmd_neigh_del,
1331 (parse_pgm_inst_t *)&cmd_neigh_add,
1332 (parse_pgm_inst_t *)&cmd_neigh_list,
1333 (parse_pgm_inst_t *)&cmd_logfile,
1334 (parse_pgm_inst_t *)&cmd_log,
1335 (parse_pgm_inst_t *)&cmd_saveconfig,
1336 (parse_pgm_inst_t *)&cmd_loadconfig,