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>
31 #include <aversive/error.h>
34 #include <parse_string.h>
35 #include <parse_num.h>
38 #include "xbee_atcmd.h"
39 #include "xbee_neighbor.h"
40 #include "xbee_stats.h"
41 #include "xbee_proto.h"
45 #include "parse_atcmd.h"
46 #include "parse_neighbor.h"
47 #include "parse_monitor.h"
54 extern parse_pgm_inst_t cmd_reset;
55 extern parse_pgm_inst_t cmd_bootloader;
56 extern parse_pgm_inst_t cmd_log;
57 extern parse_pgm_inst_t cmd_log_show;
58 extern parse_pgm_inst_t cmd_log_type;
59 extern parse_pgm_inst_t cmd_stack_space;
60 extern parse_pgm_inst_t cmd_scheduler;
62 static int monitor_period_ms = 1000;
63 static int monitor_running = 0;
64 static int monitor_count = 0;
65 static struct callout 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 callout range_event;
74 static int range_count = 100;
75 static int range_cur_count = 0;
77 static void monitor_cb(struct callout_manager *cm,
78 struct callout *clt, void *dummy)
80 if (monitor_current == NULL)
81 monitor_current = LIST_FIRST(&xbee_monitor_list);
83 xbeeapp_send_atcmd(monitor_current->atcmd, NULL, 0, 0, NULL, NULL);
84 monitor_current = LIST_NEXT(monitor_current, next);
85 callout_reset(cm, &monitor_event,
86 monitor_period_ms / monitor_count,
87 SINGLE, monitor_cb, NULL);
90 static void range_cb(struct callout_manager *cm,
91 struct callout *clt, void *dummy)
94 struct rc_proto_range rangepkt;
98 /* get new xmit power */
99 for (i = 1; i <= 8; i++) {
100 mask = 1 << ((range_power + i) & 0x7);
101 if (mask & range_powermask)
104 range_power = ((range_power + i) & 0x7);
106 xbeeapp_send_atcmd("PL", &range_power, sizeof(range_power), 0, NULL, NULL);
108 rangepkt.type = RC_PROTO_TYPE_RANGE;
109 rangepkt.power_level = range_power;
111 xbeeapp_send_msg(range_dstaddr, &rangepkt, sizeof(rangepkt), 0);
113 if (range_cur_count == 0) {
118 callout_reset(cm, &range_event,
120 SINGLE, range_cb, NULL);
123 /* this structure is filled when cmd_help is parsed successfully */
124 struct cmd_help_result {
126 struct xbee_atcmd_pgm *cmd;
129 /* function called when cmd_help is parsed successfully */
130 static void cmd_help_parsed(void *parsed_result, void *data)
132 struct cmd_help_result *res = parsed_result;
133 struct xbee_atcmd cmdcopy;
135 memcpy_P(&cmdcopy, res->cmd, sizeof(cmdcopy));
136 type = (cmdcopy.flags & (XBEE_ATCMD_F_READ | XBEE_ATCMD_F_WRITE));
138 case XBEE_ATCMD_F_READ:
139 printf_P(PSTR("Read-only\r\n"));
141 case XBEE_ATCMD_F_WRITE:
142 printf_P(PSTR("Write-only\r\n"));
145 printf_P(PSTR("Read-write\r\n"));
148 if (cmdcopy.flags & XBEE_ATCMD_F_PARAM_NONE)
149 printf_P(PSTR("No argument\r\n"));
150 else if (cmdcopy.flags & XBEE_ATCMD_F_PARAM_U8)
151 printf_P(PSTR("Register is unsigned 8 bits\r\n"));
152 else if (cmdcopy.flags & XBEE_ATCMD_F_PARAM_U16)
153 printf_P(PSTR("Register is unsigned 16 bits\r\n"));
154 else if (cmdcopy.flags & XBEE_ATCMD_F_PARAM_U32)
155 printf_P(PSTR("Register is unsigned 32 bits\r\n"));
156 else if (cmdcopy.flags & XBEE_ATCMD_F_PARAM_S16)
157 printf_P(PSTR("Register is signed 16 bits\r\n"));
158 else if (cmdcopy.flags & XBEE_ATCMD_F_PARAM_STRING_20B)
159 printf_P(PSTR("Register is a 20 bytes string\r\n"));
161 printf_P(PSTR("Unknown argument\r\n"));
163 printf_P(PSTR("%S\r\n"), cmdcopy.help);
165 prog_char str_help_help[] = "help";
167 parse_pgm_token_string_t cmd_help_help =
168 TOKEN_STRING_INITIALIZER(struct cmd_help_result, help, str_help_help);
170 parse_pgm_token_atcmd_t cmd_help_atcmd =
171 TOKEN_ATCMD_INITIALIZER(struct cmd_help_result, cmd, &xbee_dev,
174 prog_char help_help[] = "Help a register using an AT command";
175 parse_pgm_inst_t cmd_help = {
176 .f = cmd_help_parsed, /* function to call */
177 .data = NULL, /* 2nd arg of func */
178 .help_str = help_help,
179 .tokens = { /* token list, NULL terminated */
180 (prog_void *)&cmd_help_help,
181 (prog_void *)&cmd_help_atcmd,
188 struct cmd_neigh_del_result {
190 fixed_string_t action;
191 struct xbee_neigh *neigh;
194 static void cmd_neigh_del_parsed(void *parsed_result,
197 struct cmd_neigh_del_result *res = parsed_result;
198 xbee_neigh_del(xbee_dev, res->neigh);
201 prog_char str_neigh_del_neigh[] = "neigh";
202 parse_pgm_token_string_t cmd_neigh_del_cmd =
203 TOKEN_STRING_INITIALIZER(struct cmd_neigh_del_result, cmd,
204 str_neigh_del_neigh);
205 prog_char str_neigh_del_del[] = "del";
206 parse_pgm_token_string_t cmd_neigh_del_action =
207 TOKEN_STRING_INITIALIZER(struct cmd_neigh_del_result, action,
209 parse_pgm_token_neighbor_t cmd_neigh_del_neigh =
210 TOKEN_NEIGHBOR_INITIALIZER(struct cmd_neigh_del_result, neigh,
213 prog_char help_neigh_del[] = "delete a neighbor";
214 parse_pgm_inst_t cmd_neigh_del = {
215 .f = cmd_neigh_del_parsed, /* function to call */
216 .data = NULL, /* 2nd arg of func */
217 .help_str = help_neigh_del,
218 .tokens = { /* token list, NULL terminated */
219 (prog_void *)&cmd_neigh_del_cmd,
220 (prog_void *)&cmd_neigh_del_action,
221 (prog_void *)&cmd_neigh_del_neigh,
228 struct cmd_neigh_add_result {
230 fixed_string_t action;
235 static void cmd_neigh_add_parsed(void *parsed_result,
238 struct cmd_neigh_add_result *res = parsed_result;
239 if (xbee_neigh_add(xbee_dev, res->name, res->addr) == NULL)
240 printf_P(PSTR("name or addr already exist\r\n"));
243 prog_char str_neigh_add_neigh[] = "neigh";
244 parse_pgm_token_string_t cmd_neigh_add_cmd =
245 TOKEN_STRING_INITIALIZER(struct cmd_neigh_add_result, cmd,
246 str_neigh_add_neigh);
247 prog_char str_neigh_add_add[] = "add";
248 parse_pgm_token_string_t cmd_neigh_add_action =
249 TOKEN_STRING_INITIALIZER(struct cmd_neigh_add_result, action,
251 parse_pgm_token_string_t cmd_neigh_add_name =
252 TOKEN_STRING_INITIALIZER(struct cmd_neigh_add_result, name, NULL);
253 parse_pgm_token_num_t cmd_neigh_add_addr =
254 TOKEN_NUM_INITIALIZER(struct cmd_neigh_add_result, addr, UINT64);
256 prog_char help_neigh_add[] = "add a neighbor";
257 parse_pgm_inst_t cmd_neigh_add = {
258 .f = cmd_neigh_add_parsed, /* function to call */
259 .data = NULL, /* 2nd arg of func */
260 .help_str = help_neigh_add,
261 .tokens = { /* token list, NULL terminated */
262 (prog_void *)&cmd_neigh_add_cmd,
263 (prog_void *)&cmd_neigh_add_action,
264 (prog_void *)&cmd_neigh_add_name,
265 (prog_void *)&cmd_neigh_add_addr,
272 struct cmd_neigh_list_result {
274 fixed_string_t action;
277 static void cmd_neigh_list_parsed(void *parsed_result,
280 struct xbee_neigh *neigh;
282 LIST_FOREACH(neigh, &xbee_dev->neigh_list, next) {
283 printf_P(PSTR(" %s: 0x%.8"PRIx32"%.8"PRIx32"\r\n"),
285 (uint32_t)(neigh->addr >> 32ULL),
286 (uint32_t)(neigh->addr & 0xFFFFFFFF));
290 prog_char str_neigh_list_neigh[] = "neigh";
291 parse_pgm_token_string_t cmd_neigh_list_cmd =
292 TOKEN_STRING_INITIALIZER(struct cmd_neigh_list_result, cmd,
293 str_neigh_list_neigh);
294 prog_char str_neigh_list_list[] = "list";
295 parse_pgm_token_string_t cmd_neigh_list_action =
296 TOKEN_STRING_INITIALIZER(struct cmd_neigh_list_result, action,
297 str_neigh_list_list);
299 prog_char help_neigh_list[] = "list all knwon neighbors";
300 parse_pgm_inst_t cmd_neigh_list = {
301 .f = cmd_neigh_list_parsed, /* function to call */
302 .data = NULL, /* 2nd arg of func */
303 .help_str = help_neigh_list,
304 .tokens = { /* token list, NULL terminated */
305 (prog_void *)&cmd_neigh_list_cmd,
306 (prog_void *)&cmd_neigh_list_action,
316 /* this structure is filled when cmd_read is parsed successfully */
317 struct cmd_read_result {
319 struct xbee_atcmd_pgm *cmd;
322 /* function called when cmd_read is parsed successfully */
323 static void cmd_read_parsed(void *parsed_result,
326 struct cmd_read_result *res = parsed_result;
327 struct xbee_atcmd copy;
330 memcpy_P(©, res->cmd, sizeof(copy));
331 memcpy_P(&cmd, copy.name, 2);
333 xbeeapp_send_atcmd(cmd, NULL, 0, 1, NULL, NULL);
336 prog_char str_read_read[] = "read";
338 parse_pgm_token_string_t cmd_read_read =
339 TOKEN_STRING_INITIALIZER(struct cmd_read_result, read,
342 parse_pgm_token_atcmd_t cmd_read_atcmd =
343 TOKEN_ATCMD_INITIALIZER(struct cmd_read_result, cmd, &xbee_dev,
344 XBEE_ATCMD_F_READ, XBEE_ATCMD_F_READ);
346 prog_char help_read[] = "Read a register using an AT command";
347 parse_pgm_inst_t cmd_read = {
348 .f = cmd_read_parsed, /* function to call */
349 .data = NULL, /* 2nd arg of func */
350 .help_str = help_read,
351 .tokens = { /* token list, NULL terminated */
352 (prog_void *)&cmd_read_read,
353 (prog_void *)&cmd_read_atcmd,
361 /* this structure is filled when cmd_write is parsed successfully */
362 struct cmd_write_result {
363 fixed_string_t write;
364 struct xbee_atcmd_pgm *cmd;
372 /* function called when cmd_write is parsed successfully */
373 static void cmd_write_parsed(void *parsed_result, void *data)
375 struct cmd_write_result *res = parsed_result;
376 struct xbee_atcmd copy;
381 memcpy_P(©, res->cmd, sizeof(copy));
383 if (copy.flags & XBEE_ATCMD_F_PARAM_NONE) {
387 else if (copy.flags & XBEE_ATCMD_F_PARAM_U8) {
388 len = sizeof(res->u8);
391 else if (copy.flags & XBEE_ATCMD_F_PARAM_U16) {
392 len = sizeof(res->u16);
393 res->u16 = htons(res->u16);
396 else if (copy.flags & XBEE_ATCMD_F_PARAM_U32) {
397 len = sizeof(res->u32);
398 res->u32 = htonl(res->u32);
402 printf_P(PSTR("Unknown argument type\r\n"));
405 memcpy_P(&cmd, copy.name, 2);
407 xbeeapp_send_atcmd(cmd, param, len, 1, NULL, NULL);
410 prog_char str_write_none[] = "write";
412 parse_pgm_token_string_t cmd_write_write =
413 TOKEN_STRING_INITIALIZER(struct cmd_write_result, write,
416 parse_pgm_token_atcmd_t cmd_write_none_atcmd =
417 TOKEN_ATCMD_INITIALIZER(struct cmd_write_result, cmd,
419 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_NONE,
420 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_NONE);
422 prog_char help_write_none[] = "Send an AT command (no argument)";
424 parse_pgm_inst_t cmd_write_none = {
425 .f = cmd_write_parsed, /* function to call */
426 .data = NULL, /* 2nd arg of func */
427 .help_str = help_write_none,
428 .tokens = { /* token list, NULL terminated */
429 (prog_void *)&cmd_write_write,
430 (prog_void *)&cmd_write_none_atcmd,
435 parse_pgm_token_atcmd_t cmd_write_u8_atcmd =
436 TOKEN_ATCMD_INITIALIZER(struct cmd_write_result, cmd,
438 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U8,
439 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U8);
441 parse_pgm_token_num_t cmd_write_u8_u8 =
442 TOKEN_NUM_INITIALIZER(struct cmd_write_result, u8, UINT8);
444 prog_char help_write_u8[] = "Write a 8 bits register using an AT command";
446 parse_pgm_inst_t cmd_write_u8 = {
447 .f = cmd_write_parsed, /* function to call */
448 .data = NULL, /* 2nd arg of func */
449 .help_str = help_write_u8,
450 .tokens = { /* token list, NULL terminated */
451 (prog_void *)&cmd_write_write,
452 (prog_void *)&cmd_write_u8_atcmd,
453 (prog_void *)&cmd_write_u8_u8,
458 parse_pgm_token_atcmd_t cmd_write_u16_atcmd =
459 TOKEN_ATCMD_INITIALIZER(struct cmd_write_result, cmd,
461 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U16,
462 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U16);
464 parse_pgm_token_num_t cmd_write_u16_u16 =
465 TOKEN_NUM_INITIALIZER(struct cmd_write_result, u16, UINT16);
467 prog_char help_write_u16[] = "Write a 16 bits register using an AT command";
469 parse_pgm_inst_t cmd_write_u16 = {
470 .f = cmd_write_parsed, /* function to call */
471 .data = NULL, /* 2nd arg of func */
472 .help_str = help_write_u16,
473 .tokens = { /* token list, NULL terminated */
474 (prog_void *)&cmd_write_write,
475 (prog_void *)&cmd_write_u16_atcmd,
476 (prog_void *)&cmd_write_u16_u16,
481 parse_pgm_token_atcmd_t cmd_write_u32_atcmd =
482 TOKEN_ATCMD_INITIALIZER(struct cmd_write_result, cmd,
484 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U32,
485 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U32);
487 parse_pgm_token_num_t cmd_write_u32_u32 =
488 TOKEN_NUM_INITIALIZER(struct cmd_write_result, u32, UINT32);
490 prog_char help_write_u32[] = "Write a 32 bits register using an AT command";
492 parse_pgm_inst_t cmd_write_u32 = {
493 .f = cmd_write_parsed, /* function to call */
494 .data = NULL, /* 2nd arg of func */
495 .help_str = help_write_u32,
496 .tokens = { /* token list, NULL terminated */
497 (prog_void *)&cmd_write_write,
498 (prog_void *)&cmd_write_u32_atcmd,
499 (prog_void *)&cmd_write_u32_u32,
507 /* this structure is filled when cmd_sendmsg is parsed successfully */
508 struct cmd_sendmsg_result {
509 fixed_string_t sendmsg;
514 /* function called when cmd_sendmsg is parsed successfully */
515 static void cmd_sendmsg_parsed(void *parsed_result, void *data)
517 struct cmd_sendmsg_result *res = parsed_result;
518 xbeeapp_send_msg(res->addr, res->data, strlen(res->data), 1);
521 prog_char str_sendmsg[] = "sendmsg";
523 parse_pgm_token_string_t cmd_sendmsg_sendmsg =
524 TOKEN_STRING_INITIALIZER(struct cmd_sendmsg_result, sendmsg,
527 parse_pgm_token_num_t cmd_sendmsg_addr =
528 TOKEN_NUM_INITIALIZER(struct cmd_sendmsg_result, addr, UINT64);
530 parse_pgm_token_string_t cmd_sendmsg_data =
531 TOKEN_STRING_INITIALIZER(struct cmd_sendmsg_result, data, NULL);
533 prog_char help_sendmsg[] = "Send data to a node using its address";
535 parse_pgm_inst_t cmd_sendmsg = {
536 .f = cmd_sendmsg_parsed, /* function to call */
537 .data = NULL, /* 2nd arg of func */
538 .help_str = help_sendmsg,
539 .tokens = { /* token list, NULL terminated */
540 (prog_void *)&cmd_sendmsg_sendmsg,
541 (prog_void *)&cmd_sendmsg_addr,
542 (prog_void *)&cmd_sendmsg_data,
549 /* this structure is filled when cmd_sendmsg_name is parsed successfully */
550 struct cmd_sendmsg_name_result {
551 fixed_string_t sendmsg_name;
552 struct xbee_neigh *neigh;
556 /* function called when cmd_sendmsg_name is parsed successfully */
557 static void cmd_sendmsg_name_parsed(void *parsed_result, void *data)
559 struct cmd_sendmsg_name_result *res = parsed_result;
560 xbeeapp_send_msg(res->neigh->addr, res->data, strlen(res->data), 1);
563 parse_pgm_token_string_t cmd_sendmsg_name_sendmsg_name =
564 TOKEN_STRING_INITIALIZER(struct cmd_sendmsg_name_result, sendmsg_name,
567 parse_pgm_token_neighbor_t cmd_sendmsg_name_neigh =
568 TOKEN_NEIGHBOR_INITIALIZER(struct cmd_sendmsg_name_result, neigh,
571 parse_pgm_token_string_t cmd_sendmsg_name_data =
572 TOKEN_STRING_INITIALIZER(struct cmd_sendmsg_name_result, data, NULL);
574 prog_char help_sendmsg_name[] = "Send data to a node using its name";
576 parse_pgm_inst_t cmd_sendmsg_name = {
577 .f = cmd_sendmsg_name_parsed, /* function to call */
578 .data = NULL, /* 2nd arg of func */
579 .help_str = help_sendmsg_name,
580 .tokens = { /* token list, NULL terminated */
581 (prog_void *)&cmd_sendmsg_name_sendmsg_name,
582 (prog_void *)&cmd_sendmsg_name_neigh,
583 (prog_void *)&cmd_sendmsg_name_data,
591 /* this structure is filled when cmd_range is parsed successfully */
592 struct cmd_range_result {
593 fixed_string_t range;
594 fixed_string_t action;
597 /* function called when cmd_range is parsed successfully */
598 static void cmd_range_parsed(void *parsed_result, void *data)
600 struct cmd_range_result *res = parsed_result;
602 if (!strcmp_P(res->action, PSTR("show"))) {
603 printf_P(PSTR("range infos:\r\n"));
604 printf_P(PSTR(" range period %d\r\n"), range_period_ms);
605 printf_P(PSTR(" range count %d\r\n"), range_count);
606 printf_P(PSTR(" range powermask 0x%x\r\n"), range_powermask);
607 printf_P(PSTR(" range dstaddr 0x%.8"PRIx32"%.8"PRIx32"\r\n"),
608 (uint32_t)(range_dstaddr >> 32ULL),
609 (uint32_t)(range_dstaddr & 0xFFFFFFFF));
612 printf_P(PSTR(" range test is running\r\n"));
614 printf_P(PSTR(" range test is not running\r\n"));
616 else if (!strcmp(res->action, "start")) {
618 printf_P(PSTR("already running\r\n"));
621 range_cur_count = range_count;
622 callout_init(&range_event);
623 callout_reset(&cm, &range_event, 0,
624 SINGLE, range_cb, NULL);
627 else if (!strcmp(res->action, "end")) {
628 if (range_running == 0) {
629 printf_P(PSTR("not running\r\n"));
633 callout_stop(&cm, &range_event);
637 prog_char str_range[] = "range";
638 prog_char str_range_tokens[] = "show#start#end";
640 parse_pgm_token_string_t cmd_range_range =
641 TOKEN_STRING_INITIALIZER(struct cmd_range_result, range,
643 parse_pgm_token_string_t cmd_range_action =
644 TOKEN_STRING_INITIALIZER(struct cmd_range_result, action,
647 prog_char help_range[] = "start/stop/show current rangeing";
649 parse_pgm_inst_t cmd_range = {
650 .f = cmd_range_parsed, /* function to call */
651 .data = NULL, /* 2nd arg of func */
652 .help_str = help_range,
653 .tokens = { /* token list, NULL terminated */
654 (prog_void *)&cmd_range_range,
655 (prog_void *)&cmd_range_action,
662 /* this structure is filled when cmd_range_period is parsed successfully */
663 struct cmd_range_period_result {
664 fixed_string_t range;
665 fixed_string_t action;
669 /* function called when cmd_range_period is parsed successfully */
670 static void cmd_range_period_parsed(void *parsed_result, void *data)
672 struct cmd_range_period_result *res = parsed_result;
674 if (res->period < 10) {
675 printf_P(PSTR("error, minimum period is 10 ms\r\n"));
679 range_period_ms = res->period;
682 prog_char str_period[] = "period";
684 parse_pgm_token_string_t cmd_range_period_range_period =
685 TOKEN_STRING_INITIALIZER(struct cmd_range_period_result, range,
687 parse_pgm_token_string_t cmd_range_period_action =
688 TOKEN_STRING_INITIALIZER(struct cmd_range_period_result, action,
690 parse_pgm_token_num_t cmd_range_period_period =
691 TOKEN_NUM_INITIALIZER(struct cmd_range_period_result, period, UINT32);
693 prog_char help_range_period[] = "set range test period";
695 parse_pgm_inst_t cmd_range_period = {
696 .f = cmd_range_period_parsed, /* function to call */
697 .data = NULL, /* 2nd arg of func */
698 .help_str = help_range_period,
699 .tokens = { /* token list, NULL terminated */
700 (prog_void *)&cmd_range_period_range_period,
701 (prog_void *)&cmd_range_period_action,
702 (prog_void *)&cmd_range_period_period,
709 /* this structure is filled when cmd_range_count is parsed successfully */
710 struct cmd_range_count_result {
711 fixed_string_t range;
712 fixed_string_t action;
716 /* function called when cmd_range_count is parsed successfully */
717 static void cmd_range_count_parsed(void *parsed_result, void *data)
719 struct cmd_range_count_result *res = parsed_result;
720 range_count = res->count;
723 prog_char str_count[] = "count";
725 parse_pgm_token_string_t cmd_range_count_range_count =
726 TOKEN_STRING_INITIALIZER(struct cmd_range_count_result, range,
728 parse_pgm_token_string_t cmd_range_count_action =
729 TOKEN_STRING_INITIALIZER(struct cmd_range_count_result, action,
731 parse_pgm_token_num_t cmd_range_count_count =
732 TOKEN_NUM_INITIALIZER(struct cmd_range_count_result, count, UINT32);
735 prog_char help_range_count[] = "set range test count";
737 parse_pgm_inst_t cmd_range_count = {
738 .f = cmd_range_count_parsed, /* function to call */
739 .data = NULL, /* 2nd arg of func */
740 .help_str = help_range_count,
741 .tokens = { /* token list, NULL terminated */
742 (prog_void *)&cmd_range_count_range_count,
743 (prog_void *)&cmd_range_count_action,
744 (prog_void *)&cmd_range_count_count,
751 /* this structure is filled when cmd_range_powermask is parsed successfully */
752 struct cmd_range_powermask_result {
753 fixed_string_t range;
754 fixed_string_t action;
758 /* function called when cmd_range_powermask is parsed successfully */
759 static void cmd_range_powermask_parsed(void *parsed_result, void *data)
761 struct cmd_range_powermask_result *res = parsed_result;
762 range_powermask = res->powermask;
765 prog_char str_powermask[] = "powermask";
767 parse_pgm_token_string_t cmd_range_powermask_range_powermask =
768 TOKEN_STRING_INITIALIZER(struct cmd_range_powermask_result, range,
770 parse_pgm_token_string_t cmd_range_powermask_action =
771 TOKEN_STRING_INITIALIZER(struct cmd_range_powermask_result, action,
773 parse_pgm_token_num_t cmd_range_powermask_powermask =
774 TOKEN_NUM_INITIALIZER(struct cmd_range_powermask_result, powermask,
778 prog_char help_range_powermask[] = "set range test powermask";
780 parse_pgm_inst_t cmd_range_powermask = {
781 .f = cmd_range_powermask_parsed, /* function to call */
782 .data = NULL, /* 2nd arg of func */
783 .help_str = help_range_powermask,
784 .tokens = { /* token list, NULL terminated */
785 (prog_void *)&cmd_range_powermask_range_powermask,
786 (prog_void *)&cmd_range_powermask_action,
787 (prog_void *)&cmd_range_powermask_powermask,
794 /* this structure is filled when cmd_range_dstaddr is parsed successfully */
795 struct cmd_range_dstaddr_result {
796 fixed_string_t range;
797 fixed_string_t action;
801 /* function called when cmd_range_dstaddr is parsed successfully */
802 static void cmd_range_dstaddr_parsed(void *parsed_result, void *data)
804 struct cmd_range_dstaddr_result *res = parsed_result;
805 range_dstaddr = res->dstaddr;
808 prog_char str_dstaddr[] = "dstaddr";
810 parse_pgm_token_string_t cmd_range_dstaddr_range_dstaddr =
811 TOKEN_STRING_INITIALIZER(struct cmd_range_dstaddr_result, range,
813 parse_pgm_token_string_t cmd_range_dstaddr_action =
814 TOKEN_STRING_INITIALIZER(struct cmd_range_dstaddr_result, action,
816 parse_pgm_token_num_t cmd_range_dstaddr_dstaddr =
817 TOKEN_NUM_INITIALIZER(struct cmd_range_dstaddr_result, dstaddr, UINT64);
820 prog_char help_range_dstaddr[] = "set register rangeing dstaddr";
822 parse_pgm_inst_t cmd_range_dstaddr = {
823 .f = cmd_range_dstaddr_parsed, /* function to call */
824 .data = NULL, /* 2nd arg of func */
825 .help_str = help_range_dstaddr,
826 .tokens = { /* token list, NULL terminated */
827 (prog_void *)&cmd_range_dstaddr_range_dstaddr,
828 (prog_void *)&cmd_range_dstaddr_action,
829 (prog_void *)&cmd_range_dstaddr_dstaddr,
837 /* this structure is filled when cmd_monitor is parsed successfully */
838 struct cmd_monitor_result {
839 fixed_string_t monitor;
840 fixed_string_t action;
843 /* function called when cmd_monitor is parsed successfully */
844 static void cmd_monitor_parsed(void *parsed_result, void *data)
846 struct cmd_monitor_result *res = parsed_result;
847 struct monitor_reg *m;
849 if (!strcmp_P(res->action, PSTR("show"))) {
850 printf_P(PSTR("monitor period is %d ms, %d regs in list\r\n"),
851 monitor_period_ms, monitor_count);
852 LIST_FOREACH(m, &xbee_monitor_list, next)
853 printf_P(PSTR(" %S\r\n"), m->desc);
855 else if (!strcmp_P(res->action, PSTR("start"))) {
856 if (monitor_running) {
857 printf_P(PSTR("already running\r\n"));
860 if (monitor_count == 0) {
861 printf_P(PSTR("no regs to be monitored\r\n"));
864 callout_init(&monitor_event);
865 callout_reset(&cm, &monitor_event, 0, SINGLE, monitor_cb, NULL);
867 monitor_current = LIST_FIRST(&xbee_monitor_list);
868 printf_P(PSTR("monitor cb: %S %s\r\n"),
869 monitor_current->desc,
870 monitor_current->atcmd);
873 else if (!strcmp_P(res->action, PSTR("end"))) {
874 if (monitor_running == 0) {
875 printf_P(PSTR("not running\r\n"));
879 callout_stop(&cm, &monitor_event);
883 prog_char str_monitor[] = "monitor";
884 prog_char str_monitor_tokens[] = "show#start#end";
886 parse_pgm_token_string_t cmd_monitor_monitor =
887 TOKEN_STRING_INITIALIZER(struct cmd_monitor_result, monitor,
889 parse_pgm_token_string_t cmd_monitor_action =
890 TOKEN_STRING_INITIALIZER(struct cmd_monitor_result, action,
893 prog_char help_monitor[] = "start/stop/show current monitoring";
895 parse_pgm_inst_t cmd_monitor = {
896 .f = cmd_monitor_parsed, /* function to call */
897 .data = NULL, /* 2nd arg of func */
898 .help_str = help_monitor,
899 .tokens = { /* token list, NULL terminated */
900 (prog_void *)&cmd_monitor_monitor,
901 (prog_void *)&cmd_monitor_action,
908 /* this structure is filled when cmd_monitor_add is parsed successfully */
909 struct cmd_monitor_add_result {
910 fixed_string_t monitor;
911 fixed_string_t action;
912 struct xbee_atcmd_pgm *cmd;
915 /* function called when cmd_monitor_add is parsed successfully */
916 static void cmd_monitor_add_parsed(void *parsed_result, void *data)
918 struct cmd_monitor_add_result *res = parsed_result;
919 struct monitor_reg *m;
920 struct xbee_atcmd copy;
922 memcpy_P(©, res->cmd, sizeof(copy));
923 LIST_FOREACH(m, &xbee_monitor_list, next) {
924 if (!strcmp_P(m->atcmd, copy.name))
929 printf_P(PSTR("already exist\r\n"));
933 m = malloc(sizeof(*m));
935 printf_P(PSTR("no mem\r\n"));
939 strcpy_P(m->atcmd, copy.name);
940 LIST_INSERT_HEAD(&xbee_monitor_list, m, next);
944 prog_char str_monitor_add[] = "add";
946 parse_pgm_token_string_t cmd_monitor_add_monitor_add =
947 TOKEN_STRING_INITIALIZER(struct cmd_monitor_add_result, monitor,
949 parse_pgm_token_string_t cmd_monitor_add_action =
950 TOKEN_STRING_INITIALIZER(struct cmd_monitor_add_result, action,
952 parse_pgm_token_atcmd_t cmd_monitor_add_atcmd =
953 TOKEN_ATCMD_INITIALIZER(struct cmd_monitor_add_result, cmd, &xbee_dev,
954 XBEE_ATCMD_F_READ, XBEE_ATCMD_F_READ);
957 prog_char help_monitor_add[] = "add a register in monitor list";
959 parse_pgm_inst_t cmd_monitor_add = {
960 .f = cmd_monitor_add_parsed, /* function to call */
961 .data = NULL, /* 2nd arg of func */
962 .help_str = help_monitor_add,
963 .tokens = { /* token list, NULL terminated */
964 (prog_void *)&cmd_monitor_add_monitor_add,
965 (prog_void *)&cmd_monitor_add_action,
966 (prog_void *)&cmd_monitor_add_atcmd,
973 /* this structure is filled when cmd_monitor_period is parsed successfully */
974 struct cmd_monitor_period_result {
975 fixed_string_t monitor;
976 fixed_string_t action;
980 /* function called when cmd_monitor_period is parsed successfully */
981 static void cmd_monitor_period_parsed(void *parsed_result, void *data)
983 struct cmd_monitor_period_result *res = parsed_result;
985 if (res->period < 100) {
986 printf_P(PSTR("error, minimum period is 100 ms\r\n"));
990 monitor_period_ms = res->period;
993 prog_char str_monitor_period[] = "period";
995 parse_pgm_token_string_t cmd_monitor_period_monitor_period =
996 TOKEN_STRING_INITIALIZER(struct cmd_monitor_period_result, monitor,
998 parse_pgm_token_string_t cmd_monitor_period_action =
999 TOKEN_STRING_INITIALIZER(struct cmd_monitor_period_result, action,
1000 str_monitor_period);
1001 parse_pgm_token_num_t cmd_monitor_period_period =
1002 TOKEN_NUM_INITIALIZER(struct cmd_monitor_period_result, period, UINT32);
1005 prog_char help_monitor_period[] = "set register monitoring period";
1007 parse_pgm_inst_t cmd_monitor_period = {
1008 .f = cmd_monitor_period_parsed, /* function to call */
1009 .data = NULL, /* 2nd arg of func */
1010 .help_str = help_monitor_period,
1011 .tokens = { /* token list, NULL terminated */
1012 (prog_void *)&cmd_monitor_period_monitor_period,
1013 (prog_void *)&cmd_monitor_period_action,
1014 (prog_void *)&cmd_monitor_period_period,
1021 /* this structure is filled when cmd_monitor_del is parsed successfully */
1022 struct cmd_monitor_del_result {
1023 fixed_string_t monitor;
1024 fixed_string_t action;
1025 struct monitor_reg *m;
1028 /* function called when cmd_monitor_del is parsed successfully */
1029 static void cmd_monitor_del_parsed(void *parsed_result, void *data)
1031 struct cmd_monitor_del_result *res = parsed_result;
1033 monitor_current = LIST_NEXT(res->m, next);
1034 LIST_REMOVE(res->m, next);
1037 if (monitor_count == 0) {
1038 printf_P(PSTR("Disable monitoring, no more event\r\n"));
1039 callout_stop(&cm, &monitor_event);
1040 monitor_running = 0;
1045 prog_char str_monitor_del[] = "del";
1047 parse_pgm_token_string_t cmd_monitor_del_monitor_del =
1048 TOKEN_STRING_INITIALIZER(struct cmd_monitor_del_result, monitor,
1050 parse_pgm_token_string_t cmd_monitor_del_action =
1051 TOKEN_STRING_INITIALIZER(struct cmd_monitor_del_result, action,
1053 parse_pgm_token_monitor_t cmd_monitor_del_atcmd =
1054 TOKEN_MONITOR_INITIALIZER(struct cmd_monitor_del_result, m);
1057 prog_char help_monitor_del[] = "del a register in monitor list";
1059 parse_pgm_inst_t cmd_monitor_del = {
1060 .f = cmd_monitor_del_parsed, /* function to call */
1061 .data = NULL, /* 2nd arg of func */
1062 .help_str = help_monitor_del,
1063 .tokens = { /* token list, NULL terminated */
1064 (prog_void *)&cmd_monitor_del_monitor_del,
1065 (prog_void *)&cmd_monitor_del_action,
1066 (prog_void *)&cmd_monitor_del_atcmd,
1074 /* this structure is filled when cmd_ping is parsed successfully */
1075 struct cmd_ping_result {
1076 fixed_string_t ping;
1079 /* function called when cmd_ping is parsed successfully */
1080 static void cmd_ping_parsed(void *parsed_result, void *data)
1082 xbeeapp_send_atcmd("VL", NULL, 0, 1, NULL, NULL);
1085 prog_char str_ping[] = "ping";
1087 parse_pgm_token_string_t cmd_ping_ping =
1088 TOKEN_STRING_INITIALIZER(struct cmd_ping_result, ping,
1091 prog_char help_ping[] = "Send a ping to the xbee device";
1093 parse_pgm_inst_t cmd_ping = {
1094 .f = cmd_ping_parsed, /* function to call */
1095 .data = NULL, /* 2nd arg of func */
1096 .help_str = help_ping,
1097 .tokens = { /* token list, NULL terminated */
1098 (prog_void *)&cmd_ping_ping,
1105 /* this structure is filled when cmd_raw is parsed successfully */
1106 struct cmd_raw_result {
1110 /* function called when cmd_raw is parsed successfully */
1111 static void cmd_raw_parsed(void *parsed_result, void *data)
1113 printf_P(PSTR("switched to raw mode, CTRL-D to exit\r\n"));
1114 rdline_stop(&xbeeboard.rdl); /* don't display prompt when return */
1118 prog_char str_raw[] = "raw";
1120 parse_pgm_token_string_t cmd_raw_raw =
1121 TOKEN_STRING_INITIALIZER(struct cmd_raw_result, raw,
1124 prog_char help_raw[] = "Switch to raw mode";
1126 parse_pgm_inst_t cmd_raw = {
1127 .f = cmd_raw_parsed, /* function to call */
1128 .data = NULL, /* 2nd arg of func */
1129 .help_str = help_raw,
1130 .tokens = { /* token list, NULL terminated */
1131 (prog_void *)&cmd_raw_raw,
1138 /* this structure is filled when cmd_dump is parsed successfully */
1139 struct cmd_dump_result {
1140 fixed_string_t dump;
1141 fixed_string_t onoff;
1144 /* function called when cmd_dump is parsed successfully */
1145 static void cmd_dump_parsed(void *parsed_result, void *data)
1147 struct cmd_dump_result *res = parsed_result;
1148 if (!strcmp(res->onoff, "on"))
1154 prog_char str_dump[] = "dump";
1155 prog_char str_dump_onoff[] = "on#off";
1157 parse_pgm_token_string_t cmd_dump_dump =
1158 TOKEN_STRING_INITIALIZER(struct cmd_dump_result, dump,
1161 parse_pgm_token_string_t cmd_dump_onoff =
1162 TOKEN_STRING_INITIALIZER(struct cmd_dump_result, onoff,
1165 prog_char help_dump[] = "enable/disable hexdump of received packets";
1167 parse_pgm_inst_t cmd_dump = {
1168 .f = cmd_dump_parsed, /* function to call */
1169 .data = NULL, /* 2nd arg of func */
1170 .help_str = help_dump,
1171 .tokens = { /* token list, NULL terminated */
1172 (prog_void *)&cmd_dump_dump,
1173 (prog_void *)&cmd_dump_onoff,
1180 /* this structure is filled when cmd_debug is parsed successfully */
1181 struct cmd_debug_result {
1182 fixed_string_t debug;
1183 fixed_string_t onoff;
1186 /* function called when cmd_debug is parsed successfully */
1187 static void cmd_debug_parsed(void *parsed_result, void *data)
1189 struct cmd_debug_result *res = parsed_result;
1190 if (!strcmp(res->onoff, "on"))
1196 prog_char str_debug[] = "debug";
1197 prog_char str_debug_onoff[] = "on#off";
1199 parse_pgm_token_string_t cmd_debug_debug =
1200 TOKEN_STRING_INITIALIZER(struct cmd_debug_result, debug,
1203 parse_pgm_token_string_t cmd_debug_onoff =
1204 TOKEN_STRING_INITIALIZER(struct cmd_debug_result, onoff,
1207 prog_char help_debug[] = "enable/disable additionnal debug";
1209 parse_pgm_inst_t cmd_debug = {
1210 .f = cmd_debug_parsed, /* function to call */
1211 .data = NULL, /* 2nd arg of func */
1212 .help_str = help_debug,
1213 .tokens = { /* token list, NULL terminated */
1214 (prog_void *)&cmd_debug_debug,
1215 (prog_void *)&cmd_debug_onoff,
1221 /**********************************************************/
1223 /* this structure is filled when cmd_baudrate is parsed successfully */
1224 struct cmd_baudrate_result {
1225 fixed_string_t arg0;
1229 /* function called when cmd_baudrate is parsed successfully */
1230 static void cmd_baudrate_parsed(void * parsed_result, __attribute__((unused)) void *data)
1232 struct cmd_baudrate_result *res = parsed_result;
1233 struct uart_config c;
1235 uart_getconf(XBEE_UART, &c);
1236 c.baudrate = res->arg1;
1237 uart_setconf(XBEE_UART, &c);
1240 prog_char str_baudrate_arg0[] = "baudrate";
1241 parse_pgm_token_string_t cmd_baudrate_arg0 =
1242 TOKEN_STRING_INITIALIZER(struct cmd_baudrate_result, arg0,
1244 parse_pgm_token_num_t cmd_baudrate_arg1 =
1245 TOKEN_NUM_INITIALIZER(struct cmd_baudrate_result, arg1,
1248 prog_char help_baudrate[] = "Change xbee baudrate";
1249 parse_pgm_inst_t cmd_baudrate = {
1250 .f = cmd_baudrate_parsed, /* function to call */
1251 .data = NULL, /* 2nd arg of func */
1252 .help_str = help_baudrate,
1253 .tokens = { /* token list, NULL terminated */
1254 (prog_void *)&cmd_baudrate_arg0,
1255 (prog_void *)&cmd_baudrate_arg1,
1263 parse_pgm_ctx_t main_ctx[] = {
1265 /* commands_gen.c */
1266 (parse_pgm_inst_t *)&cmd_reset,
1267 (parse_pgm_inst_t *)&cmd_bootloader,
1268 (parse_pgm_inst_t *)&cmd_log,
1269 (parse_pgm_inst_t *)&cmd_log_show,
1270 (parse_pgm_inst_t *)&cmd_log_type,
1271 (parse_pgm_inst_t *)&cmd_stack_space,
1272 (parse_pgm_inst_t *)&cmd_scheduler,
1273 (parse_pgm_inst_t *)&cmd_help,
1274 (parse_pgm_inst_t *)&cmd_neigh_del,
1275 (parse_pgm_inst_t *)&cmd_neigh_add,
1276 (parse_pgm_inst_t *)&cmd_neigh_list,
1277 (parse_pgm_inst_t *)&cmd_read,
1278 (parse_pgm_inst_t *)&cmd_write_none,
1279 (parse_pgm_inst_t *)&cmd_write_u8,
1280 (parse_pgm_inst_t *)&cmd_write_u16,
1281 (parse_pgm_inst_t *)&cmd_write_u32,
1282 (parse_pgm_inst_t *)&cmd_sendmsg,
1283 (parse_pgm_inst_t *)&cmd_sendmsg_name,
1284 (parse_pgm_inst_t *)&cmd_range,
1285 (parse_pgm_inst_t *)&cmd_range_period,
1286 (parse_pgm_inst_t *)&cmd_range_count,
1287 (parse_pgm_inst_t *)&cmd_range_powermask,
1288 (parse_pgm_inst_t *)&cmd_range_dstaddr,
1289 (parse_pgm_inst_t *)&cmd_monitor,
1290 (parse_pgm_inst_t *)&cmd_monitor_period,
1291 (parse_pgm_inst_t *)&cmd_monitor_add,
1292 (parse_pgm_inst_t *)&cmd_monitor_del,
1293 (parse_pgm_inst_t *)&cmd_ping,
1294 (parse_pgm_inst_t *)&cmd_raw,
1295 (parse_pgm_inst_t *)&cmd_dump,
1296 (parse_pgm_inst_t *)&cmd_debug,
1298 (parse_pgm_inst_t *)&cmd_baudrate,