2 * Copyright Droids Corporation (2011)
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 * Revision : $Id: commands.c,v 1.9 2009-11-08 17:24:33 zer0 Exp $
20 * Olivier MATZ <zer0@droids-corp.org>
28 #include <aversive/pgmspace.h>
29 #include <aversive/queue.h>
30 #include <aversive/endian.h>
33 #include <parse_string.h>
34 #include <parse_num.h>
36 #include "xbee_atcmd.h"
37 #include "xbee_neighbor.h"
38 #include "xbee_stats.h"
39 #include "xbee_proto.h"
43 #include "parse_atcmd.h"
44 #include "parse_neighbor.h"
45 #include "parse_monitor.h"
51 extern parse_pgm_inst_t cmd_reset;
52 extern parse_pgm_inst_t cmd_bootloader;
53 extern parse_pgm_inst_t cmd_log;
54 extern parse_pgm_inst_t cmd_log_show;
55 extern parse_pgm_inst_t cmd_log_type;
56 extern parse_pgm_inst_t cmd_stack_space;
57 extern parse_pgm_inst_t cmd_scheduler;
59 static int monitor_period_ms = 1000;
60 static int monitor_running = 0;
61 static int monitor_count = 0;
62 static struct callout 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 callout range_event;
71 static int range_count = 100;
72 static int range_cur_count = 0;
74 static void monitor_cb(struct callout_manager *cm,
75 struct callout *clt, void *dummy)
77 if (monitor_current == NULL)
78 monitor_current = LIST_FIRST(&xbee_monitor_list);
80 xbeeapp_send_atcmd(monitor_current->atcmd, NULL, 0, 0, NULL, NULL);
81 monitor_current = LIST_NEXT(monitor_current, next);
82 callout_reset(cm, &monitor_event,
83 monitor_period_ms / monitor_count,
84 SINGLE, monitor_cb, NULL);
87 static void range_cb(struct callout_manager *cm,
88 struct callout *clt, void *dummy)
91 struct rc_proto_range rangepkt;
95 /* get new xmit power */
96 for (i = 1; i <= 8; i++) {
97 mask = 1 << ((range_power + i) & 0x7);
98 if (mask & range_powermask)
101 range_power = ((range_power + i) & 0x7);
103 xbeeapp_send_atcmd("PL", &range_power, sizeof(range_power), 0, NULL, NULL);
105 rangepkt.type = RC_PROTO_TYPE_RANGE;
106 rangepkt.power_level = range_power;
108 xbeeapp_send_msg(range_dstaddr, &rangepkt, sizeof(rangepkt), 0);
110 if (range_cur_count == 0) {
115 callout_reset(cm, &range_event,
117 SINGLE, range_cb, NULL);
120 /* this structure is filled when cmd_help is parsed successfully */
121 struct cmd_help_result {
123 struct xbee_atcmd_pgm *cmd;
126 /* function called when cmd_help is parsed successfully */
127 static void cmd_help_parsed(void *parsed_result, void *data)
129 struct cmd_help_result *res = parsed_result;
130 struct xbee_atcmd cmdcopy;
132 memcpy_P(&cmdcopy, res->cmd, sizeof(cmdcopy));
133 type = (cmdcopy.flags & (XBEE_ATCMD_F_READ | XBEE_ATCMD_F_WRITE));
135 case XBEE_ATCMD_F_READ:
136 printf_P(PSTR("Read-only\r\n"));
138 case XBEE_ATCMD_F_WRITE:
139 printf_P(PSTR("Write-only\r\n"));
142 printf_P(PSTR("Read-write\r\n"));
145 if (cmdcopy.flags & XBEE_ATCMD_F_PARAM_NONE)
146 printf_P(PSTR("No argument\r\n"));
147 else if (cmdcopy.flags & XBEE_ATCMD_F_PARAM_U8)
148 printf_P(PSTR("Register is unsigned 8 bits\r\n"));
149 else if (cmdcopy.flags & XBEE_ATCMD_F_PARAM_U16)
150 printf_P(PSTR("Register is unsigned 16 bits\r\n"));
151 else if (cmdcopy.flags & XBEE_ATCMD_F_PARAM_U32)
152 printf_P(PSTR("Register is unsigned 32 bits\r\n"));
153 else if (cmdcopy.flags & XBEE_ATCMD_F_PARAM_S16)
154 printf_P(PSTR("Register is signed 16 bits\r\n"));
155 else if (cmdcopy.flags & XBEE_ATCMD_F_PARAM_STRING_20B)
156 printf_P(PSTR("Register is a 20 bytes string\r\n"));
158 printf_P(PSTR("Unknown argument\r\n"));
160 printf_P(PSTR("%S\r\n"), cmdcopy.help);
162 prog_char str_help_help[] = "help";
164 parse_pgm_token_string_t cmd_help_help =
165 TOKEN_STRING_INITIALIZER(struct cmd_help_result, help, str_help_help);
167 parse_pgm_token_atcmd_t cmd_help_atcmd =
168 TOKEN_ATCMD_INITIALIZER(struct cmd_help_result, cmd, &xbee_dev,
171 prog_char help_help[] = "Help a register using an AT command";
172 parse_pgm_inst_t cmd_help = {
173 .f = cmd_help_parsed, /* function to call */
174 .data = NULL, /* 2nd arg of func */
175 .help_str = help_help,
176 .tokens = { /* token list, NULL terminated */
177 (prog_void *)&cmd_help_help,
178 (prog_void *)&cmd_help_atcmd,
185 struct cmd_neigh_del_result {
187 fixed_string_t action;
188 struct xbee_neigh *neigh;
191 static void cmd_neigh_del_parsed(void *parsed_result,
194 struct cmd_neigh_del_result *res = parsed_result;
195 xbee_neigh_del(xbee_dev, res->neigh);
198 prog_char str_neigh_del_neigh[] = "neigh";
199 parse_pgm_token_string_t cmd_neigh_del_cmd =
200 TOKEN_STRING_INITIALIZER(struct cmd_neigh_del_result, cmd,
201 str_neigh_del_neigh);
202 prog_char str_neigh_del_del[] = "del";
203 parse_pgm_token_string_t cmd_neigh_del_action =
204 TOKEN_STRING_INITIALIZER(struct cmd_neigh_del_result, action,
206 parse_pgm_token_neighbor_t cmd_neigh_del_neigh =
207 TOKEN_NEIGHBOR_INITIALIZER(struct cmd_neigh_del_result, neigh,
210 prog_char help_neigh_del[] = "delete a neighbor";
211 parse_pgm_inst_t cmd_neigh_del = {
212 .f = cmd_neigh_del_parsed, /* function to call */
213 .data = NULL, /* 2nd arg of func */
214 .help_str = help_neigh_del,
215 .tokens = { /* token list, NULL terminated */
216 (prog_void *)&cmd_neigh_del_cmd,
217 (prog_void *)&cmd_neigh_del_action,
218 (prog_void *)&cmd_neigh_del_neigh,
225 struct cmd_neigh_add_result {
227 fixed_string_t action;
232 static void cmd_neigh_add_parsed(void *parsed_result,
235 struct cmd_neigh_add_result *res = parsed_result;
236 if (xbee_neigh_add(xbee_dev, res->name, res->addr) == NULL)
237 printf_P(PSTR("name or addr already exist\r\n"));
240 prog_char str_neigh_add_neigh[] = "neigh";
241 parse_pgm_token_string_t cmd_neigh_add_cmd =
242 TOKEN_STRING_INITIALIZER(struct cmd_neigh_add_result, cmd,
243 str_neigh_add_neigh);
244 prog_char str_neigh_add_add[] = "add";
245 parse_pgm_token_string_t cmd_neigh_add_action =
246 TOKEN_STRING_INITIALIZER(struct cmd_neigh_add_result, action,
248 parse_pgm_token_string_t cmd_neigh_add_name =
249 TOKEN_STRING_INITIALIZER(struct cmd_neigh_add_result, name, NULL);
250 parse_pgm_token_num_t cmd_neigh_add_addr =
251 TOKEN_NUM_INITIALIZER(struct cmd_neigh_add_result, addr, UINT64);
253 prog_char help_neigh_add[] = "add a neighbor";
254 parse_pgm_inst_t cmd_neigh_add = {
255 .f = cmd_neigh_add_parsed, /* function to call */
256 .data = NULL, /* 2nd arg of func */
257 .help_str = help_neigh_add,
258 .tokens = { /* token list, NULL terminated */
259 (prog_void *)&cmd_neigh_add_cmd,
260 (prog_void *)&cmd_neigh_add_action,
261 (prog_void *)&cmd_neigh_add_name,
262 (prog_void *)&cmd_neigh_add_addr,
269 struct cmd_neigh_list_result {
271 fixed_string_t action;
274 static void cmd_neigh_list_parsed(void *parsed_result,
277 struct xbee_neigh *neigh;
279 LIST_FOREACH(neigh, &xbee_dev->neigh_list, next) {
280 printf_P(PSTR(" %s: 0x%.8"PRIx32"%.8"PRIx32"\r\n"),
282 (uint32_t)(neigh->addr >> 32ULL),
283 (uint32_t)(neigh->addr & 0xFFFFFFFF));
287 prog_char str_neigh_list_neigh[] = "neigh";
288 parse_pgm_token_string_t cmd_neigh_list_cmd =
289 TOKEN_STRING_INITIALIZER(struct cmd_neigh_list_result, cmd,
290 str_neigh_list_neigh);
291 prog_char str_neigh_list_list[] = "list";
292 parse_pgm_token_string_t cmd_neigh_list_action =
293 TOKEN_STRING_INITIALIZER(struct cmd_neigh_list_result, action,
294 str_neigh_list_list);
296 prog_char help_neigh_list[] = "list all knwon neighbors";
297 parse_pgm_inst_t cmd_neigh_list = {
298 .f = cmd_neigh_list_parsed, /* function to call */
299 .data = NULL, /* 2nd arg of func */
300 .help_str = help_neigh_list,
301 .tokens = { /* token list, NULL terminated */
302 (prog_void *)&cmd_neigh_list_cmd,
303 (prog_void *)&cmd_neigh_list_action,
313 /* this structure is filled when cmd_read is parsed successfully */
314 struct cmd_read_result {
316 struct xbee_atcmd_pgm *cmd;
319 /* function called when cmd_read is parsed successfully */
320 static void cmd_read_parsed(void *parsed_result,
323 struct cmd_read_result *res = parsed_result;
324 struct xbee_atcmd copy;
327 memcpy_P(©, res->cmd, sizeof(copy));
328 memcpy_P(&cmd, copy.name, 2);
330 xbeeapp_send_atcmd(cmd, NULL, 0, 1, NULL, NULL);
333 prog_char str_read_read[] = "read";
335 parse_pgm_token_string_t cmd_read_read =
336 TOKEN_STRING_INITIALIZER(struct cmd_read_result, read,
339 parse_pgm_token_atcmd_t cmd_read_atcmd =
340 TOKEN_ATCMD_INITIALIZER(struct cmd_read_result, cmd, &xbee_dev,
341 XBEE_ATCMD_F_READ, XBEE_ATCMD_F_READ);
343 prog_char help_read[] = "Read a register using an AT command";
344 parse_pgm_inst_t cmd_read = {
345 .f = cmd_read_parsed, /* function to call */
346 .data = NULL, /* 2nd arg of func */
347 .help_str = help_read,
348 .tokens = { /* token list, NULL terminated */
349 (prog_void *)&cmd_read_read,
350 (prog_void *)&cmd_read_atcmd,
358 /* this structure is filled when cmd_write is parsed successfully */
359 struct cmd_write_result {
360 fixed_string_t write;
361 struct xbee_atcmd_pgm *cmd;
369 /* function called when cmd_write is parsed successfully */
370 static void cmd_write_parsed(void *parsed_result, void *data)
372 struct cmd_write_result *res = parsed_result;
373 struct xbee_atcmd copy;
378 memcpy_P(©, res->cmd, sizeof(copy));
380 if (copy.flags & XBEE_ATCMD_F_PARAM_NONE) {
384 else if (copy.flags & XBEE_ATCMD_F_PARAM_U8) {
385 len = sizeof(res->u8);
388 else if (copy.flags & XBEE_ATCMD_F_PARAM_U16) {
389 len = sizeof(res->u16);
390 res->u16 = htons(res->u16);
393 else if (copy.flags & XBEE_ATCMD_F_PARAM_U32) {
394 len = sizeof(res->u32);
395 res->u32 = htonl(res->u32);
399 printf_P(PSTR("Unknown argument type\r\n"));
402 memcpy_P(&cmd, copy.name, 2);
404 xbeeapp_send_atcmd(cmd, param, len, 1, NULL, NULL);
407 prog_char str_write_none[] = "write";
409 parse_pgm_token_string_t cmd_write_write =
410 TOKEN_STRING_INITIALIZER(struct cmd_write_result, write,
413 parse_pgm_token_atcmd_t cmd_write_none_atcmd =
414 TOKEN_ATCMD_INITIALIZER(struct cmd_write_result, cmd,
416 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_NONE,
417 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_NONE);
419 prog_char help_write_none[] = "Send an AT command (no argument)";
421 parse_pgm_inst_t cmd_write_none = {
422 .f = cmd_write_parsed, /* function to call */
423 .data = NULL, /* 2nd arg of func */
424 .help_str = help_write_none,
425 .tokens = { /* token list, NULL terminated */
426 (prog_void *)&cmd_write_write,
427 (prog_void *)&cmd_write_none_atcmd,
432 parse_pgm_token_atcmd_t cmd_write_u8_atcmd =
433 TOKEN_ATCMD_INITIALIZER(struct cmd_write_result, cmd,
435 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U8,
436 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U8);
438 parse_pgm_token_num_t cmd_write_u8_u8 =
439 TOKEN_NUM_INITIALIZER(struct cmd_write_result, u8, UINT8);
441 prog_char help_write_u8[] = "Write a 8 bits register using an AT command";
443 parse_pgm_inst_t cmd_write_u8 = {
444 .f = cmd_write_parsed, /* function to call */
445 .data = NULL, /* 2nd arg of func */
446 .help_str = help_write_u8,
447 .tokens = { /* token list, NULL terminated */
448 (prog_void *)&cmd_write_write,
449 (prog_void *)&cmd_write_u8_atcmd,
450 (prog_void *)&cmd_write_u8_u8,
455 parse_pgm_token_atcmd_t cmd_write_u16_atcmd =
456 TOKEN_ATCMD_INITIALIZER(struct cmd_write_result, cmd,
458 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U16,
459 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U16);
461 parse_pgm_token_num_t cmd_write_u16_u16 =
462 TOKEN_NUM_INITIALIZER(struct cmd_write_result, u16, UINT16);
464 prog_char help_write_u16[] = "Write a 16 bits register using an AT command";
466 parse_pgm_inst_t cmd_write_u16 = {
467 .f = cmd_write_parsed, /* function to call */
468 .data = NULL, /* 2nd arg of func */
469 .help_str = help_write_u16,
470 .tokens = { /* token list, NULL terminated */
471 (prog_void *)&cmd_write_write,
472 (prog_void *)&cmd_write_u16_atcmd,
473 (prog_void *)&cmd_write_u16_u16,
478 parse_pgm_token_atcmd_t cmd_write_u32_atcmd =
479 TOKEN_ATCMD_INITIALIZER(struct cmd_write_result, cmd,
481 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U32,
482 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U32);
484 parse_pgm_token_num_t cmd_write_u32_u32 =
485 TOKEN_NUM_INITIALIZER(struct cmd_write_result, u32, UINT32);
487 prog_char help_write_u32[] = "Write a 32 bits register using an AT command";
489 parse_pgm_inst_t cmd_write_u32 = {
490 .f = cmd_write_parsed, /* function to call */
491 .data = NULL, /* 2nd arg of func */
492 .help_str = help_write_u32,
493 .tokens = { /* token list, NULL terminated */
494 (prog_void *)&cmd_write_write,
495 (prog_void *)&cmd_write_u32_atcmd,
496 (prog_void *)&cmd_write_u32_u32,
504 /* this structure is filled when cmd_sendmsg is parsed successfully */
505 struct cmd_sendmsg_result {
506 fixed_string_t sendmsg;
511 /* function called when cmd_sendmsg is parsed successfully */
512 static void cmd_sendmsg_parsed(void *parsed_result, void *data)
514 struct cmd_sendmsg_result *res = parsed_result;
515 xbeeapp_send_msg(res->addr, res->data, strlen(res->data), 1);
518 prog_char str_sendmsg[] = "sendmsg";
520 parse_pgm_token_string_t cmd_sendmsg_sendmsg =
521 TOKEN_STRING_INITIALIZER(struct cmd_sendmsg_result, sendmsg,
524 parse_pgm_token_num_t cmd_sendmsg_addr =
525 TOKEN_NUM_INITIALIZER(struct cmd_sendmsg_result, addr, UINT64);
527 parse_pgm_token_string_t cmd_sendmsg_data =
528 TOKEN_STRING_INITIALIZER(struct cmd_sendmsg_result, data, NULL);
530 prog_char help_sendmsg[] = "Send data to a node using its address";
532 parse_pgm_inst_t cmd_sendmsg = {
533 .f = cmd_sendmsg_parsed, /* function to call */
534 .data = NULL, /* 2nd arg of func */
535 .help_str = help_sendmsg,
536 .tokens = { /* token list, NULL terminated */
537 (prog_void *)&cmd_sendmsg_sendmsg,
538 (prog_void *)&cmd_sendmsg_addr,
539 (prog_void *)&cmd_sendmsg_data,
546 /* this structure is filled when cmd_sendmsg_name is parsed successfully */
547 struct cmd_sendmsg_name_result {
548 fixed_string_t sendmsg_name;
549 struct xbee_neigh *neigh;
553 /* function called when cmd_sendmsg_name is parsed successfully */
554 static void cmd_sendmsg_name_parsed(void *parsed_result, void *data)
556 struct cmd_sendmsg_name_result *res = parsed_result;
557 xbeeapp_send_msg(res->neigh->addr, res->data, strlen(res->data), 1);
560 parse_pgm_token_string_t cmd_sendmsg_name_sendmsg_name =
561 TOKEN_STRING_INITIALIZER(struct cmd_sendmsg_name_result, sendmsg_name,
564 parse_pgm_token_neighbor_t cmd_sendmsg_name_neigh =
565 TOKEN_NEIGHBOR_INITIALIZER(struct cmd_sendmsg_name_result, neigh,
568 parse_pgm_token_string_t cmd_sendmsg_name_data =
569 TOKEN_STRING_INITIALIZER(struct cmd_sendmsg_name_result, data, NULL);
571 prog_char help_sendmsg_name[] = "Send data to a node using its name";
573 parse_pgm_inst_t cmd_sendmsg_name = {
574 .f = cmd_sendmsg_name_parsed, /* function to call */
575 .data = NULL, /* 2nd arg of func */
576 .help_str = help_sendmsg_name,
577 .tokens = { /* token list, NULL terminated */
578 (prog_void *)&cmd_sendmsg_name_sendmsg_name,
579 (prog_void *)&cmd_sendmsg_name_neigh,
580 (prog_void *)&cmd_sendmsg_name_data,
588 /* this structure is filled when cmd_range is parsed successfully */
589 struct cmd_range_result {
590 fixed_string_t range;
591 fixed_string_t action;
594 /* function called when cmd_range is parsed successfully */
595 static void cmd_range_parsed(void *parsed_result, void *data)
597 struct cmd_range_result *res = parsed_result;
599 if (!strcmp_P(res->action, PSTR("show"))) {
600 printf_P(PSTR("range infos:\r\n"));
601 printf_P(PSTR(" range period %d\r\n"), range_period_ms);
602 printf_P(PSTR(" range count %d\r\n"), range_count);
603 printf_P(PSTR(" range powermask 0x%x\r\n"), range_powermask);
604 printf_P(PSTR(" range dstaddr 0x%.8"PRIx32"%.8"PRIx32"\r\n"),
605 (uint32_t)(range_dstaddr >> 32ULL),
606 (uint32_t)(range_dstaddr & 0xFFFFFFFF));
609 printf_P(PSTR(" range test is running\r\n"));
611 printf_P(PSTR(" range test is not running\r\n"));
613 else if (!strcmp(res->action, "start")) {
615 printf_P(PSTR("already running\r\n"));
618 range_cur_count = range_count;
619 callout_init(&range_event);
620 callout_reset(&cm, &range_event, 0,
621 SINGLE, range_cb, NULL);
624 else if (!strcmp(res->action, "end")) {
625 if (range_running == 0) {
626 printf_P(PSTR("not running\r\n"));
630 callout_stop(&cm, &range_event);
634 prog_char str_range[] = "range";
635 prog_char str_range_tokens[] = "show#start#end";
637 parse_pgm_token_string_t cmd_range_range =
638 TOKEN_STRING_INITIALIZER(struct cmd_range_result, range,
640 parse_pgm_token_string_t cmd_range_action =
641 TOKEN_STRING_INITIALIZER(struct cmd_range_result, action,
644 prog_char help_range[] = "start/stop/show current rangeing";
646 parse_pgm_inst_t cmd_range = {
647 .f = cmd_range_parsed, /* function to call */
648 .data = NULL, /* 2nd arg of func */
649 .help_str = help_range,
650 .tokens = { /* token list, NULL terminated */
651 (prog_void *)&cmd_range_range,
652 (prog_void *)&cmd_range_action,
659 /* this structure is filled when cmd_range_period is parsed successfully */
660 struct cmd_range_period_result {
661 fixed_string_t range;
662 fixed_string_t action;
666 /* function called when cmd_range_period is parsed successfully */
667 static void cmd_range_period_parsed(void *parsed_result, void *data)
669 struct cmd_range_period_result *res = parsed_result;
671 if (res->period < 10) {
672 printf_P(PSTR("error, minimum period is 10 ms\r\n"));
676 range_period_ms = res->period;
679 prog_char str_period[] = "period";
681 parse_pgm_token_string_t cmd_range_period_range_period =
682 TOKEN_STRING_INITIALIZER(struct cmd_range_period_result, range,
684 parse_pgm_token_string_t cmd_range_period_action =
685 TOKEN_STRING_INITIALIZER(struct cmd_range_period_result, action,
687 parse_pgm_token_num_t cmd_range_period_period =
688 TOKEN_NUM_INITIALIZER(struct cmd_range_period_result, period, UINT32);
690 prog_char help_range_period[] = "set range test period";
692 parse_pgm_inst_t cmd_range_period = {
693 .f = cmd_range_period_parsed, /* function to call */
694 .data = NULL, /* 2nd arg of func */
695 .help_str = help_range_period,
696 .tokens = { /* token list, NULL terminated */
697 (prog_void *)&cmd_range_period_range_period,
698 (prog_void *)&cmd_range_period_action,
699 (prog_void *)&cmd_range_period_period,
706 /* this structure is filled when cmd_range_count is parsed successfully */
707 struct cmd_range_count_result {
708 fixed_string_t range;
709 fixed_string_t action;
713 /* function called when cmd_range_count is parsed successfully */
714 static void cmd_range_count_parsed(void *parsed_result, void *data)
716 struct cmd_range_count_result *res = parsed_result;
717 range_count = res->count;
720 prog_char str_count[] = "count";
722 parse_pgm_token_string_t cmd_range_count_range_count =
723 TOKEN_STRING_INITIALIZER(struct cmd_range_count_result, range,
725 parse_pgm_token_string_t cmd_range_count_action =
726 TOKEN_STRING_INITIALIZER(struct cmd_range_count_result, action,
728 parse_pgm_token_num_t cmd_range_count_count =
729 TOKEN_NUM_INITIALIZER(struct cmd_range_count_result, count, UINT32);
732 prog_char help_range_count[] = "set range test count";
734 parse_pgm_inst_t cmd_range_count = {
735 .f = cmd_range_count_parsed, /* function to call */
736 .data = NULL, /* 2nd arg of func */
737 .help_str = help_range_count,
738 .tokens = { /* token list, NULL terminated */
739 (prog_void *)&cmd_range_count_range_count,
740 (prog_void *)&cmd_range_count_action,
741 (prog_void *)&cmd_range_count_count,
748 /* this structure is filled when cmd_range_powermask is parsed successfully */
749 struct cmd_range_powermask_result {
750 fixed_string_t range;
751 fixed_string_t action;
755 /* function called when cmd_range_powermask is parsed successfully */
756 static void cmd_range_powermask_parsed(void *parsed_result, void *data)
758 struct cmd_range_powermask_result *res = parsed_result;
759 range_powermask = res->powermask;
762 prog_char str_powermask[] = "powermask";
764 parse_pgm_token_string_t cmd_range_powermask_range_powermask =
765 TOKEN_STRING_INITIALIZER(struct cmd_range_powermask_result, range,
767 parse_pgm_token_string_t cmd_range_powermask_action =
768 TOKEN_STRING_INITIALIZER(struct cmd_range_powermask_result, action,
770 parse_pgm_token_num_t cmd_range_powermask_powermask =
771 TOKEN_NUM_INITIALIZER(struct cmd_range_powermask_result, powermask,
775 prog_char help_range_powermask[] = "set range test powermask";
777 parse_pgm_inst_t cmd_range_powermask = {
778 .f = cmd_range_powermask_parsed, /* function to call */
779 .data = NULL, /* 2nd arg of func */
780 .help_str = help_range_powermask,
781 .tokens = { /* token list, NULL terminated */
782 (prog_void *)&cmd_range_powermask_range_powermask,
783 (prog_void *)&cmd_range_powermask_action,
784 (prog_void *)&cmd_range_powermask_powermask,
791 /* this structure is filled when cmd_range_dstaddr is parsed successfully */
792 struct cmd_range_dstaddr_result {
793 fixed_string_t range;
794 fixed_string_t action;
798 /* function called when cmd_range_dstaddr is parsed successfully */
799 static void cmd_range_dstaddr_parsed(void *parsed_result, void *data)
801 struct cmd_range_dstaddr_result *res = parsed_result;
802 range_dstaddr = res->dstaddr;
805 prog_char str_dstaddr[] = "dstaddr";
807 parse_pgm_token_string_t cmd_range_dstaddr_range_dstaddr =
808 TOKEN_STRING_INITIALIZER(struct cmd_range_dstaddr_result, range,
810 parse_pgm_token_string_t cmd_range_dstaddr_action =
811 TOKEN_STRING_INITIALIZER(struct cmd_range_dstaddr_result, action,
813 parse_pgm_token_num_t cmd_range_dstaddr_dstaddr =
814 TOKEN_NUM_INITIALIZER(struct cmd_range_dstaddr_result, dstaddr, UINT64);
817 prog_char help_range_dstaddr[] = "set register rangeing dstaddr";
819 parse_pgm_inst_t cmd_range_dstaddr = {
820 .f = cmd_range_dstaddr_parsed, /* function to call */
821 .data = NULL, /* 2nd arg of func */
822 .help_str = help_range_dstaddr,
823 .tokens = { /* token list, NULL terminated */
824 (prog_void *)&cmd_range_dstaddr_range_dstaddr,
825 (prog_void *)&cmd_range_dstaddr_action,
826 (prog_void *)&cmd_range_dstaddr_dstaddr,
834 /* this structure is filled when cmd_monitor is parsed successfully */
835 struct cmd_monitor_result {
836 fixed_string_t monitor;
837 fixed_string_t action;
840 /* function called when cmd_monitor is parsed successfully */
841 static void cmd_monitor_parsed(void *parsed_result, void *data)
843 struct cmd_monitor_result *res = parsed_result;
844 struct monitor_reg *m;
846 if (!strcmp_P(res->action, PSTR("show"))) {
847 printf_P(PSTR("monitor period is %d ms, %d regs in list\r\n"),
848 monitor_period_ms, monitor_count);
849 LIST_FOREACH(m, &xbee_monitor_list, next)
850 printf_P(PSTR(" %S\r\n"), m->desc);
852 else if (!strcmp_P(res->action, PSTR("start"))) {
853 if (monitor_running) {
854 printf_P(PSTR("already running\r\n"));
857 if (monitor_count == 0) {
858 printf_P(PSTR("no regs to be monitored\r\n"));
861 callout_init(&monitor_event);
862 callout_reset(&cm, &monitor_event, 0, SINGLE, monitor_cb, NULL);
864 monitor_current = LIST_FIRST(&xbee_monitor_list);
865 printf_P(PSTR("monitor cb: %S %s\r\n"),
866 monitor_current->desc,
867 monitor_current->atcmd);
870 else if (!strcmp_P(res->action, PSTR("end"))) {
871 if (monitor_running == 0) {
872 printf_P(PSTR("not running\r\n"));
876 callout_stop(&cm, &monitor_event);
880 prog_char str_monitor[] = "monitor";
881 prog_char str_monitor_tokens[] = "show#start#end";
883 parse_pgm_token_string_t cmd_monitor_monitor =
884 TOKEN_STRING_INITIALIZER(struct cmd_monitor_result, monitor,
886 parse_pgm_token_string_t cmd_monitor_action =
887 TOKEN_STRING_INITIALIZER(struct cmd_monitor_result, action,
890 prog_char help_monitor[] = "start/stop/show current monitoring";
892 parse_pgm_inst_t cmd_monitor = {
893 .f = cmd_monitor_parsed, /* function to call */
894 .data = NULL, /* 2nd arg of func */
895 .help_str = help_monitor,
896 .tokens = { /* token list, NULL terminated */
897 (prog_void *)&cmd_monitor_monitor,
898 (prog_void *)&cmd_monitor_action,
905 /* this structure is filled when cmd_monitor_add is parsed successfully */
906 struct cmd_monitor_add_result {
907 fixed_string_t monitor;
908 fixed_string_t action;
909 struct xbee_atcmd_pgm *cmd;
912 /* function called when cmd_monitor_add is parsed successfully */
913 static void cmd_monitor_add_parsed(void *parsed_result, void *data)
915 struct cmd_monitor_add_result *res = parsed_result;
916 struct monitor_reg *m;
917 struct xbee_atcmd copy;
919 memcpy_P(©, res->cmd, sizeof(copy));
920 LIST_FOREACH(m, &xbee_monitor_list, next) {
921 if (!strcmp_P(m->atcmd, copy.name))
926 printf_P(PSTR("already exist\r\n"));
930 m = malloc(sizeof(*m));
932 printf_P(PSTR("no mem\r\n"));
936 strcpy_P(m->atcmd, copy.name);
937 LIST_INSERT_HEAD(&xbee_monitor_list, m, next);
941 prog_char str_monitor_add[] = "add";
943 parse_pgm_token_string_t cmd_monitor_add_monitor_add =
944 TOKEN_STRING_INITIALIZER(struct cmd_monitor_add_result, monitor,
946 parse_pgm_token_string_t cmd_monitor_add_action =
947 TOKEN_STRING_INITIALIZER(struct cmd_monitor_add_result, action,
949 parse_pgm_token_atcmd_t cmd_monitor_add_atcmd =
950 TOKEN_ATCMD_INITIALIZER(struct cmd_monitor_add_result, cmd, &xbee_dev,
951 XBEE_ATCMD_F_READ, XBEE_ATCMD_F_READ);
954 prog_char help_monitor_add[] = "add a register in monitor list";
956 parse_pgm_inst_t cmd_monitor_add = {
957 .f = cmd_monitor_add_parsed, /* function to call */
958 .data = NULL, /* 2nd arg of func */
959 .help_str = help_monitor_add,
960 .tokens = { /* token list, NULL terminated */
961 (prog_void *)&cmd_monitor_add_monitor_add,
962 (prog_void *)&cmd_monitor_add_action,
963 (prog_void *)&cmd_monitor_add_atcmd,
970 /* this structure is filled when cmd_monitor_period is parsed successfully */
971 struct cmd_monitor_period_result {
972 fixed_string_t monitor;
973 fixed_string_t action;
977 /* function called when cmd_monitor_period is parsed successfully */
978 static void cmd_monitor_period_parsed(void *parsed_result, void *data)
980 struct cmd_monitor_period_result *res = parsed_result;
982 if (res->period < 100) {
983 printf_P(PSTR("error, minimum period is 100 ms\r\n"));
987 monitor_period_ms = res->period;
990 prog_char str_monitor_period[] = "period";
992 parse_pgm_token_string_t cmd_monitor_period_monitor_period =
993 TOKEN_STRING_INITIALIZER(struct cmd_monitor_period_result, monitor,
995 parse_pgm_token_string_t cmd_monitor_period_action =
996 TOKEN_STRING_INITIALIZER(struct cmd_monitor_period_result, action,
998 parse_pgm_token_num_t cmd_monitor_period_period =
999 TOKEN_NUM_INITIALIZER(struct cmd_monitor_period_result, period, UINT32);
1002 prog_char help_monitor_period[] = "set register monitoring period";
1004 parse_pgm_inst_t cmd_monitor_period = {
1005 .f = cmd_monitor_period_parsed, /* function to call */
1006 .data = NULL, /* 2nd arg of func */
1007 .help_str = help_monitor_period,
1008 .tokens = { /* token list, NULL terminated */
1009 (prog_void *)&cmd_monitor_period_monitor_period,
1010 (prog_void *)&cmd_monitor_period_action,
1011 (prog_void *)&cmd_monitor_period_period,
1018 /* this structure is filled when cmd_monitor_del is parsed successfully */
1019 struct cmd_monitor_del_result {
1020 fixed_string_t monitor;
1021 fixed_string_t action;
1022 struct monitor_reg *m;
1025 /* function called when cmd_monitor_del is parsed successfully */
1026 static void cmd_monitor_del_parsed(void *parsed_result, void *data)
1028 struct cmd_monitor_del_result *res = parsed_result;
1030 monitor_current = LIST_NEXT(res->m, next);
1031 LIST_REMOVE(res->m, next);
1034 if (monitor_count == 0) {
1035 printf_P(PSTR("Disable monitoring, no more event\r\n"));
1036 callout_stop(&cm, &monitor_event);
1037 monitor_running = 0;
1042 prog_char str_monitor_del[] = "del";
1044 parse_pgm_token_string_t cmd_monitor_del_monitor_del =
1045 TOKEN_STRING_INITIALIZER(struct cmd_monitor_del_result, monitor,
1047 parse_pgm_token_string_t cmd_monitor_del_action =
1048 TOKEN_STRING_INITIALIZER(struct cmd_monitor_del_result, action,
1050 parse_pgm_token_monitor_t cmd_monitor_del_atcmd =
1051 TOKEN_MONITOR_INITIALIZER(struct cmd_monitor_del_result, m);
1054 prog_char help_monitor_del[] = "del a register in monitor list";
1056 parse_pgm_inst_t cmd_monitor_del = {
1057 .f = cmd_monitor_del_parsed, /* function to call */
1058 .data = NULL, /* 2nd arg of func */
1059 .help_str = help_monitor_del,
1060 .tokens = { /* token list, NULL terminated */
1061 (prog_void *)&cmd_monitor_del_monitor_del,
1062 (prog_void *)&cmd_monitor_del_action,
1063 (prog_void *)&cmd_monitor_del_atcmd,
1071 /* this structure is filled when cmd_ping is parsed successfully */
1072 struct cmd_ping_result {
1073 fixed_string_t ping;
1076 /* function called when cmd_ping is parsed successfully */
1077 static void cmd_ping_parsed(void *parsed_result, void *data)
1079 xbeeapp_send_atcmd("VL", NULL, 0, 1, NULL, NULL);
1082 prog_char str_ping[] = "ping";
1084 parse_pgm_token_string_t cmd_ping_ping =
1085 TOKEN_STRING_INITIALIZER(struct cmd_ping_result, ping,
1088 prog_char help_ping[] = "Send a ping to the xbee device";
1090 parse_pgm_inst_t cmd_ping = {
1091 .f = cmd_ping_parsed, /* function to call */
1092 .data = NULL, /* 2nd arg of func */
1093 .help_str = help_ping,
1094 .tokens = { /* token list, NULL terminated */
1095 (prog_void *)&cmd_ping_ping,
1102 /* this structure is filled when cmd_raw is parsed successfully */
1103 struct cmd_raw_result {
1107 /* function called when cmd_raw is parsed successfully */
1108 static void cmd_raw_parsed(void *parsed_result, void *data)
1110 printf_P(PSTR("switched to raw mode, CTRL-D to exit\r\n"));
1111 rdline_stop(&xbeeboard.rdl); /* don't display prompt when return */
1115 prog_char str_raw[] = "raw";
1117 parse_pgm_token_string_t cmd_raw_raw =
1118 TOKEN_STRING_INITIALIZER(struct cmd_raw_result, raw,
1121 prog_char help_raw[] = "Switch to raw mode";
1123 parse_pgm_inst_t cmd_raw = {
1124 .f = cmd_raw_parsed, /* function to call */
1125 .data = NULL, /* 2nd arg of func */
1126 .help_str = help_raw,
1127 .tokens = { /* token list, NULL terminated */
1128 (prog_void *)&cmd_raw_raw,
1135 /* this structure is filled when cmd_dump is parsed successfully */
1136 struct cmd_dump_result {
1137 fixed_string_t dump;
1138 fixed_string_t onoff;
1141 /* function called when cmd_dump is parsed successfully */
1142 static void cmd_dump_parsed(void *parsed_result, void *data)
1144 struct cmd_dump_result *res = parsed_result;
1145 if (!strcmp(res->onoff, "on"))
1151 prog_char str_dump[] = "dump";
1152 prog_char str_dump_onoff[] = "on#off";
1154 parse_pgm_token_string_t cmd_dump_dump =
1155 TOKEN_STRING_INITIALIZER(struct cmd_dump_result, dump,
1158 parse_pgm_token_string_t cmd_dump_onoff =
1159 TOKEN_STRING_INITIALIZER(struct cmd_dump_result, onoff,
1162 prog_char help_dump[] = "enable/disable hexdump of received packets";
1164 parse_pgm_inst_t cmd_dump = {
1165 .f = cmd_dump_parsed, /* function to call */
1166 .data = NULL, /* 2nd arg of func */
1167 .help_str = help_dump,
1168 .tokens = { /* token list, NULL terminated */
1169 (prog_void *)&cmd_dump_dump,
1170 (prog_void *)&cmd_dump_onoff,
1177 /* this structure is filled when cmd_debug is parsed successfully */
1178 struct cmd_debug_result {
1179 fixed_string_t debug;
1180 fixed_string_t onoff;
1183 /* function called when cmd_debug is parsed successfully */
1184 static void cmd_debug_parsed(void *parsed_result, void *data)
1186 struct cmd_debug_result *res = parsed_result;
1187 if (!strcmp(res->onoff, "on"))
1193 prog_char str_debug[] = "debug";
1194 prog_char str_debug_onoff[] = "on#off";
1196 parse_pgm_token_string_t cmd_debug_debug =
1197 TOKEN_STRING_INITIALIZER(struct cmd_debug_result, debug,
1200 parse_pgm_token_string_t cmd_debug_onoff =
1201 TOKEN_STRING_INITIALIZER(struct cmd_debug_result, onoff,
1204 prog_char help_debug[] = "enable/disable additionnal debug";
1206 parse_pgm_inst_t cmd_debug = {
1207 .f = cmd_debug_parsed, /* function to call */
1208 .data = NULL, /* 2nd arg of func */
1209 .help_str = help_debug,
1210 .tokens = { /* token list, NULL terminated */
1211 (prog_void *)&cmd_debug_debug,
1212 (prog_void *)&cmd_debug_onoff,
1220 parse_pgm_ctx_t main_ctx[] = {
1222 /* commands_gen.c */
1223 (parse_pgm_inst_t *)&cmd_reset,
1224 (parse_pgm_inst_t *)&cmd_bootloader,
1225 (parse_pgm_inst_t *)&cmd_log,
1226 (parse_pgm_inst_t *)&cmd_log_show,
1227 (parse_pgm_inst_t *)&cmd_log_type,
1228 (parse_pgm_inst_t *)&cmd_stack_space,
1229 (parse_pgm_inst_t *)&cmd_scheduler,
1230 (parse_pgm_inst_t *)&cmd_help,
1231 (parse_pgm_inst_t *)&cmd_neigh_del,
1232 (parse_pgm_inst_t *)&cmd_neigh_add,
1233 (parse_pgm_inst_t *)&cmd_neigh_list,
1234 (parse_pgm_inst_t *)&cmd_read,
1235 (parse_pgm_inst_t *)&cmd_write_none,
1236 (parse_pgm_inst_t *)&cmd_write_u8,
1237 (parse_pgm_inst_t *)&cmd_write_u16,
1238 (parse_pgm_inst_t *)&cmd_write_u32,
1239 (parse_pgm_inst_t *)&cmd_sendmsg,
1240 (parse_pgm_inst_t *)&cmd_sendmsg_name,
1241 (parse_pgm_inst_t *)&cmd_range,
1242 (parse_pgm_inst_t *)&cmd_range_period,
1243 (parse_pgm_inst_t *)&cmd_range_count,
1244 (parse_pgm_inst_t *)&cmd_range_powermask,
1245 (parse_pgm_inst_t *)&cmd_range_dstaddr,
1246 (parse_pgm_inst_t *)&cmd_monitor,
1247 (parse_pgm_inst_t *)&cmd_monitor_period,
1248 (parse_pgm_inst_t *)&cmd_monitor_add,
1249 (parse_pgm_inst_t *)&cmd_monitor_del,
1250 (parse_pgm_inst_t *)&cmd_ping,
1251 (parse_pgm_inst_t *)&cmd_raw,
1252 (parse_pgm_inst_t *)&cmd_dump,
1253 (parse_pgm_inst_t *)&cmd_debug,