update ldscript
[protos/xbee-avr.git] / commands.c
1 /*
2  *  Copyright Droids Corporation (2011)
3  *
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.
8  *
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.
13  *
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
17  *
18  *  Revision : $Id: commands.c,v 1.9 2009-11-08 17:24:33 zer0 Exp $
19  *
20  *  Olivier MATZ <zer0@droids-corp.org>
21  */
22
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <inttypes.h>
27 #include <aversive.h>
28 #include <aversive/pgmspace.h>
29 #include <aversive/queue.h>
30 #include <aversive/endian.h>
31 #include <aversive/error.h>
32 #include <parse.h>
33 #include <rdline.h>
34 #include <parse_string.h>
35 #include <parse_num.h>
36 #include <uart.h>
37
38 #include "xbee_atcmd.h"
39 #include "xbee_neighbor.h"
40 #include "xbee_stats.h"
41 #include "xbee_proto.h"
42 #include "xbee.h"
43
44 #include "callout.h"
45 #include "parse_atcmd.h"
46 #include "parse_neighbor.h"
47 #include "parse_monitor.h"
48
49 #include "rc_proto.h"
50 #include "main.h"
51 #include "cmdline.h"
52
53 /* commands_gen.c */
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;
61
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;
67
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;
76
77 static void monitor_cb(struct callout_manager *cm,
78                        struct callout *clt, void *dummy)
79 {
80         if (monitor_current == NULL)
81                 monitor_current = LIST_FIRST(&xbee_monitor_list);
82
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);
88 }
89
90 static void range_cb(struct callout_manager *cm,
91                      struct callout *clt, void *dummy)
92 {
93         uint8_t i, mask;
94         struct rc_proto_range rangepkt;
95
96         range_cur_count--;
97
98         /* get new xmit power */
99         for (i = 1; i <= 8; i++) {
100                 mask = 1 << ((range_power + i) & 0x7);
101                 if (mask & range_powermask)
102                         break;
103         }
104         range_power = ((range_power + i) & 0x7);
105
106         xbeeapp_send_atcmd("PL", &range_power, sizeof(range_power), 0, NULL, NULL);
107
108         rangepkt.type = RC_PROTO_TYPE_RANGE;
109         rangepkt.power_level = range_power;
110
111         xbeeapp_send_msg(range_dstaddr, &rangepkt, sizeof(rangepkt), 0);
112
113         if (range_cur_count == 0) {
114                 range_running = 0;
115                 return;
116         }
117
118         callout_reset(cm, &range_event,
119                       range_period_ms,
120                       SINGLE, range_cb, NULL);
121 }
122
123 /* this structure is filled when cmd_help is parsed successfully */
124 struct cmd_help_result {
125         fixed_string_t help;
126         struct xbee_atcmd_pgm *cmd;
127 };
128
129 /* function called when cmd_help is parsed successfully */
130 static void cmd_help_parsed(void *parsed_result, void *data)
131 {
132         struct cmd_help_result *res = parsed_result;
133         struct xbee_atcmd cmdcopy;
134         int type;
135         memcpy_P(&cmdcopy, res->cmd, sizeof(cmdcopy));
136         type = (cmdcopy.flags & (XBEE_ATCMD_F_READ | XBEE_ATCMD_F_WRITE));
137         switch (type) {
138                 case XBEE_ATCMD_F_READ:
139                         printf_P(PSTR("Read-only\r\n"));
140                         break;
141                 case XBEE_ATCMD_F_WRITE:
142                         printf_P(PSTR("Write-only\r\n"));
143                         break;
144                 default:
145                         printf_P(PSTR("Read-write\r\n"));
146                         break;
147         }
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"));
160         else
161                 printf_P(PSTR("Unknown argument\r\n"));
162
163         printf_P(PSTR("%S\r\n"), cmdcopy.help);
164 }
165 prog_char str_help_help[] = "help";
166
167 parse_pgm_token_string_t cmd_help_help =
168         TOKEN_STRING_INITIALIZER(struct cmd_help_result, help, str_help_help);
169
170 parse_pgm_token_atcmd_t cmd_help_atcmd =
171         TOKEN_ATCMD_INITIALIZER(struct cmd_help_result, cmd, &xbee_dev,
172                                 0, 0);
173
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,
182                 NULL,
183         },
184 };
185
186 /* ************* */
187
188 struct cmd_neigh_del_result {
189         fixed_string_t cmd;
190         fixed_string_t action;
191         struct xbee_neigh *neigh;
192 };
193
194 static void cmd_neigh_del_parsed(void *parsed_result,
195                                 void *data)
196 {
197         struct cmd_neigh_del_result *res = parsed_result;
198         xbee_neigh_del(xbee_dev, res->neigh);
199 }
200
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,
208                                  str_neigh_del_del);
209 parse_pgm_token_neighbor_t cmd_neigh_del_neigh =
210         TOKEN_NEIGHBOR_INITIALIZER(struct cmd_neigh_del_result, neigh,
211                                    &xbee_dev);
212
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,
222                 NULL,
223         },
224 };
225
226 /* ************* */
227
228 struct cmd_neigh_add_result {
229         fixed_string_t cmd;
230         fixed_string_t action;
231         fixed_string_t name;
232         uint64_t addr;
233 };
234
235 static void cmd_neigh_add_parsed(void *parsed_result,
236                                  void *data)
237 {
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"));
241 }
242
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,
250                                  str_neigh_add_add);
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);
255
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,
266                 NULL,
267         },
268 };
269
270 /* ************* */
271
272 struct cmd_neigh_list_result {
273         fixed_string_t cmd;
274         fixed_string_t action;
275 };
276
277 static void cmd_neigh_list_parsed(void *parsed_result,
278                                 void *data)
279 {
280         struct xbee_neigh *neigh;
281
282         LIST_FOREACH(neigh, &xbee_dev->neigh_list, next) {
283                 printf_P(PSTR(" %s: 0x%.8"PRIx32"%.8"PRIx32"\r\n"),
284                          neigh->name,
285                          (uint32_t)(neigh->addr >> 32ULL),
286                          (uint32_t)(neigh->addr & 0xFFFFFFFF));
287         }
288 }
289
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);
298
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,
307                 NULL,
308         },
309 };
310
311
312
313
314 /* ************* */
315
316 /* this structure is filled when cmd_read is parsed successfully */
317 struct cmd_read_result {
318         fixed_string_t read;
319         struct xbee_atcmd_pgm *cmd;
320 };
321
322 /* function called when cmd_read is parsed successfully */
323 static void cmd_read_parsed(void *parsed_result,
324                             void *data)
325 {
326         struct cmd_read_result *res = parsed_result;
327         struct xbee_atcmd copy;
328         char cmd[3];
329
330         memcpy_P(&copy, res->cmd, sizeof(copy));
331         memcpy_P(&cmd, copy.name, 2);
332         cmd[2] = '\0';
333         xbeeapp_send_atcmd(cmd, NULL, 0, 1, NULL, NULL);
334 }
335
336 prog_char str_read_read[] = "read";
337
338 parse_pgm_token_string_t cmd_read_read =
339         TOKEN_STRING_INITIALIZER(struct cmd_read_result, read,
340                                  str_read_read);
341
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);
345
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,
354                 NULL,
355         },
356 };
357
358
359 /* ************* */
360
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;
365         union {
366                 uint8_t u8;
367                 uint16_t u16;
368                 uint32_t u32;
369         };
370 };
371
372 /* function called when cmd_write is parsed successfully */
373 static void cmd_write_parsed(void *parsed_result, void *data)
374 {
375         struct cmd_write_result *res = parsed_result;
376         struct xbee_atcmd copy;
377         char cmd[3];
378         int len;
379         void *param;
380
381         memcpy_P(&copy, res->cmd, sizeof(copy));
382
383         if (copy.flags & XBEE_ATCMD_F_PARAM_NONE) {
384                 len = 0;
385                 param = NULL;
386         }
387         else if (copy.flags & XBEE_ATCMD_F_PARAM_U8) {
388                 len = sizeof(res->u8);
389                 param = &res->u8;
390         }
391         else if (copy.flags & XBEE_ATCMD_F_PARAM_U16) {
392                 len = sizeof(res->u16);
393                 res->u16 = htons(res->u16);
394                 param = &res->u16;
395         }
396         else if (copy.flags & XBEE_ATCMD_F_PARAM_U32) {
397                 len = sizeof(res->u32);
398                 res->u32 = htonl(res->u32);
399                 param = &res->u32;
400         }
401         else {
402                 printf_P(PSTR("Unknown argument type\r\n"));
403                 return;
404         }
405         memcpy_P(&cmd, copy.name, 2);
406         cmd[2] = '\0';
407         xbeeapp_send_atcmd(cmd, param, len, 1, NULL, NULL);
408 }
409
410 prog_char str_write_none[] = "write";
411
412 parse_pgm_token_string_t cmd_write_write =
413         TOKEN_STRING_INITIALIZER(struct cmd_write_result, write,
414                                  str_write_none);
415
416 parse_pgm_token_atcmd_t cmd_write_none_atcmd =
417         TOKEN_ATCMD_INITIALIZER(struct cmd_write_result, cmd,
418                                 &xbee_dev,
419                                 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_NONE,
420                                 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_NONE);
421
422 prog_char help_write_none[] = "Send an AT command (no argument)";
423
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,
431                 NULL,
432         },
433 };
434
435 parse_pgm_token_atcmd_t cmd_write_u8_atcmd =
436         TOKEN_ATCMD_INITIALIZER(struct cmd_write_result, cmd,
437                                 &xbee_dev,
438                                 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U8,
439                                 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U8);
440
441 parse_pgm_token_num_t cmd_write_u8_u8 =
442         TOKEN_NUM_INITIALIZER(struct cmd_write_result, u8, UINT8);
443
444 prog_char help_write_u8[] = "Write a 8 bits register using an AT command";
445
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,
454                 NULL,
455         },
456 };
457
458 parse_pgm_token_atcmd_t cmd_write_u16_atcmd =
459         TOKEN_ATCMD_INITIALIZER(struct cmd_write_result, cmd,
460                                 &xbee_dev,
461                                 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U16,
462                                 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U16);
463
464 parse_pgm_token_num_t cmd_write_u16_u16 =
465         TOKEN_NUM_INITIALIZER(struct cmd_write_result, u16, UINT16);
466
467 prog_char help_write_u16[] = "Write a 16 bits register using an AT command";
468
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,
477                 NULL,
478         },
479 };
480
481 parse_pgm_token_atcmd_t cmd_write_u32_atcmd =
482         TOKEN_ATCMD_INITIALIZER(struct cmd_write_result, cmd,
483                                 &xbee_dev,
484                                 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U32,
485                                 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U32);
486
487 parse_pgm_token_num_t cmd_write_u32_u32 =
488         TOKEN_NUM_INITIALIZER(struct cmd_write_result, u32, UINT32);
489
490 prog_char help_write_u32[] = "Write a 32 bits register using an AT command";
491
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,
500                 NULL,
501         },
502 };
503
504
505 /* ************* */
506
507 /* this structure is filled when cmd_sendmsg is parsed successfully */
508 struct cmd_sendmsg_result {
509         fixed_string_t sendmsg;
510         uint64_t addr;
511         fixed_string_t data;
512 };
513
514 /* function called when cmd_sendmsg is parsed successfully */
515 static void cmd_sendmsg_parsed(void *parsed_result, void *data)
516 {
517         struct cmd_sendmsg_result *res = parsed_result;
518         xbeeapp_send_msg(res->addr, res->data, strlen(res->data), 1);
519 }
520
521 prog_char str_sendmsg[] = "sendmsg";
522
523 parse_pgm_token_string_t cmd_sendmsg_sendmsg =
524         TOKEN_STRING_INITIALIZER(struct cmd_sendmsg_result, sendmsg,
525                                  str_sendmsg);
526
527 parse_pgm_token_num_t cmd_sendmsg_addr =
528         TOKEN_NUM_INITIALIZER(struct cmd_sendmsg_result, addr, UINT64);
529
530 parse_pgm_token_string_t cmd_sendmsg_data =
531         TOKEN_STRING_INITIALIZER(struct cmd_sendmsg_result, data, NULL);
532
533 prog_char help_sendmsg[] = "Send data to a node using its address";
534
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,
543                 NULL,
544         },
545 };
546
547 /* ************* */
548
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;
553         fixed_string_t data;
554 };
555
556 /* function called when cmd_sendmsg_name is parsed successfully */
557 static void cmd_sendmsg_name_parsed(void *parsed_result, void *data)
558 {
559         struct cmd_sendmsg_name_result *res = parsed_result;
560         xbeeapp_send_msg(res->neigh->addr, res->data, strlen(res->data), 1);
561 }
562
563 parse_pgm_token_string_t cmd_sendmsg_name_sendmsg_name =
564         TOKEN_STRING_INITIALIZER(struct cmd_sendmsg_name_result, sendmsg_name,
565                                  str_sendmsg);
566
567 parse_pgm_token_neighbor_t cmd_sendmsg_name_neigh =
568         TOKEN_NEIGHBOR_INITIALIZER(struct cmd_sendmsg_name_result, neigh,
569                                    &xbee_dev);
570
571 parse_pgm_token_string_t cmd_sendmsg_name_data =
572         TOKEN_STRING_INITIALIZER(struct cmd_sendmsg_name_result, data, NULL);
573
574 prog_char help_sendmsg_name[] = "Send data to a node using its name";
575
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,
584                 NULL,
585         },
586 };
587
588
589 /* ************* */
590
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;
595 };
596
597 /* function called when cmd_range is parsed successfully */
598 static void cmd_range_parsed(void *parsed_result, void *data)
599 {
600         struct cmd_range_result *res = parsed_result;
601
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));
610
611                 if (range_running)
612                         printf_P(PSTR("  range test is running\r\n"));
613                 else
614                         printf_P(PSTR("  range test is not running\r\n"));
615         }
616         else if (!strcmp(res->action, "start")) {
617                 if (range_running) {
618                         printf_P(PSTR("already running\r\n"));
619                         return;
620                 }
621                 range_cur_count = range_count;
622                 callout_init(&range_event);
623                 callout_reset(&cm, &range_event, 0,
624                               SINGLE, range_cb, NULL);
625                 range_running = 1;
626         }
627         else if (!strcmp(res->action, "end")) {
628                 if (range_running == 0) {
629                         printf_P(PSTR("not running\r\n"));
630                         return;
631                 }
632                 range_running = 0;
633                 callout_stop(&cm, &range_event);
634         }
635 }
636
637 prog_char str_range[] = "range";
638 prog_char str_range_tokens[] = "show#start#end";
639
640 parse_pgm_token_string_t cmd_range_range =
641         TOKEN_STRING_INITIALIZER(struct cmd_range_result, range,
642                                  str_range);
643 parse_pgm_token_string_t cmd_range_action =
644         TOKEN_STRING_INITIALIZER(struct cmd_range_result, action,
645                                  str_range_tokens);
646
647 prog_char help_range[] = "start/stop/show current rangeing";
648
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,
656                 NULL,
657         },
658 };
659
660 /* ************* */
661
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;
666         uint32_t period;
667 };
668
669 /* function called when cmd_range_period is parsed successfully */
670 static void cmd_range_period_parsed(void *parsed_result, void *data)
671 {
672         struct cmd_range_period_result *res = parsed_result;
673
674         if (res->period < 10) {
675                 printf_P(PSTR("error, minimum period is 10 ms\r\n"));
676                 return;
677         }
678
679         range_period_ms = res->period;
680 }
681
682 prog_char str_period[] = "period";
683
684 parse_pgm_token_string_t cmd_range_period_range_period =
685         TOKEN_STRING_INITIALIZER(struct cmd_range_period_result, range,
686                                  str_range);
687 parse_pgm_token_string_t cmd_range_period_action =
688         TOKEN_STRING_INITIALIZER(struct cmd_range_period_result, action,
689                                  str_period);
690 parse_pgm_token_num_t cmd_range_period_period =
691         TOKEN_NUM_INITIALIZER(struct cmd_range_period_result, period, UINT32);
692
693 prog_char help_range_period[] = "set range test period";
694
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,
703                 NULL,
704         },
705 };
706
707 /* ************* */
708
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;
713         uint32_t count;
714 };
715
716 /* function called when cmd_range_count is parsed successfully */
717 static void cmd_range_count_parsed(void *parsed_result, void *data)
718 {
719         struct cmd_range_count_result *res = parsed_result;
720         range_count = res->count;
721 }
722
723 prog_char str_count[] = "count";
724
725 parse_pgm_token_string_t cmd_range_count_range_count =
726         TOKEN_STRING_INITIALIZER(struct cmd_range_count_result, range,
727                                  str_range);
728 parse_pgm_token_string_t cmd_range_count_action =
729         TOKEN_STRING_INITIALIZER(struct cmd_range_count_result, action,
730                                  str_count);
731 parse_pgm_token_num_t cmd_range_count_count =
732         TOKEN_NUM_INITIALIZER(struct cmd_range_count_result, count, UINT32);
733
734
735 prog_char help_range_count[] = "set range test count";
736
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,
745                 NULL,
746         },
747 };
748
749 /* ************* */
750
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;
755         uint8_t powermask;
756 };
757
758 /* function called when cmd_range_powermask is parsed successfully */
759 static void cmd_range_powermask_parsed(void *parsed_result, void *data)
760 {
761         struct cmd_range_powermask_result *res = parsed_result;
762         range_powermask = res->powermask;
763 }
764
765 prog_char str_powermask[] = "powermask";
766
767 parse_pgm_token_string_t cmd_range_powermask_range_powermask =
768         TOKEN_STRING_INITIALIZER(struct cmd_range_powermask_result, range,
769                                  str_range);
770 parse_pgm_token_string_t cmd_range_powermask_action =
771         TOKEN_STRING_INITIALIZER(struct cmd_range_powermask_result, action,
772                                  str_powermask);
773 parse_pgm_token_num_t cmd_range_powermask_powermask =
774         TOKEN_NUM_INITIALIZER(struct cmd_range_powermask_result, powermask,
775                               UINT8);
776
777
778 prog_char help_range_powermask[] = "set range test powermask";
779
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,
788                 NULL,
789         },
790 };
791
792 /* ************* */
793
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;
798         uint64_t dstaddr;
799 };
800
801 /* function called when cmd_range_dstaddr is parsed successfully */
802 static void cmd_range_dstaddr_parsed(void *parsed_result, void *data)
803 {
804         struct cmd_range_dstaddr_result *res = parsed_result;
805         range_dstaddr = res->dstaddr;
806 }
807
808 prog_char str_dstaddr[] = "dstaddr";
809
810 parse_pgm_token_string_t cmd_range_dstaddr_range_dstaddr =
811         TOKEN_STRING_INITIALIZER(struct cmd_range_dstaddr_result, range,
812                                  str_range);
813 parse_pgm_token_string_t cmd_range_dstaddr_action =
814         TOKEN_STRING_INITIALIZER(struct cmd_range_dstaddr_result, action,
815                                  str_dstaddr);
816 parse_pgm_token_num_t cmd_range_dstaddr_dstaddr =
817         TOKEN_NUM_INITIALIZER(struct cmd_range_dstaddr_result, dstaddr, UINT64);
818
819
820 prog_char help_range_dstaddr[] = "set register rangeing dstaddr";
821
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,
830                 NULL,
831         },
832 };
833
834
835 /* ************* */
836
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;
841 };
842
843 /* function called when cmd_monitor is parsed successfully */
844 static void cmd_monitor_parsed(void *parsed_result, void *data)
845 {
846         struct cmd_monitor_result *res = parsed_result;
847         struct monitor_reg *m;
848
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);
854         }
855         else if (!strcmp_P(res->action, PSTR("start"))) {
856                 if (monitor_running) {
857                         printf_P(PSTR("already running\r\n"));
858                         return;
859                 }
860                 if (monitor_count == 0) {
861                         printf_P(PSTR("no regs to be monitored\r\n"));
862                         return;
863                 }
864                 callout_init(&monitor_event);
865                 callout_reset(&cm, &monitor_event, 0, SINGLE, monitor_cb, NULL);
866                 monitor_running = 1;
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);
871
872         }
873         else if (!strcmp_P(res->action, PSTR("end"))) {
874                 if (monitor_running == 0) {
875                         printf_P(PSTR("not running\r\n"));
876                         return;
877                 }
878                 monitor_running = 0;
879                 callout_stop(&cm, &monitor_event);
880         }
881 }
882
883 prog_char str_monitor[] = "monitor";
884 prog_char str_monitor_tokens[] = "show#start#end";
885
886 parse_pgm_token_string_t cmd_monitor_monitor =
887         TOKEN_STRING_INITIALIZER(struct cmd_monitor_result, monitor,
888                                  str_monitor);
889 parse_pgm_token_string_t cmd_monitor_action =
890         TOKEN_STRING_INITIALIZER(struct cmd_monitor_result, action,
891                                  str_monitor_tokens);
892
893 prog_char help_monitor[] = "start/stop/show current monitoring";
894
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,
902                 NULL,
903         },
904 };
905
906 /* ************* */
907
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;
913 };
914
915 /* function called when cmd_monitor_add is parsed successfully */
916 static void cmd_monitor_add_parsed(void *parsed_result, void *data)
917 {
918         struct cmd_monitor_add_result *res = parsed_result;
919         struct monitor_reg *m;
920         struct xbee_atcmd copy;
921
922         memcpy_P(&copy, res->cmd, sizeof(copy));
923         LIST_FOREACH(m, &xbee_monitor_list, next) {
924                 if (!strcmp_P(m->atcmd, copy.name))
925                         break;
926         }
927
928         if (m != NULL) {
929                 printf_P(PSTR("already exist\r\n"));
930                 return;
931         }
932
933         m = malloc(sizeof(*m));
934         if (m == NULL) {
935                 printf_P(PSTR("no mem\r\n"));
936                 return;
937         }
938         m->desc = copy.desc;
939         strcpy_P(m->atcmd, copy.name);
940         LIST_INSERT_HEAD(&xbee_monitor_list, m, next);
941         monitor_count ++;
942 }
943
944 prog_char str_monitor_add[] = "add";
945
946 parse_pgm_token_string_t cmd_monitor_add_monitor_add =
947         TOKEN_STRING_INITIALIZER(struct cmd_monitor_add_result, monitor,
948                                  str_monitor);
949 parse_pgm_token_string_t cmd_monitor_add_action =
950         TOKEN_STRING_INITIALIZER(struct cmd_monitor_add_result, action,
951                                  str_monitor_add);
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);
955
956
957 prog_char help_monitor_add[] = "add a register in monitor list";
958
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,
967                 NULL,
968         },
969 };
970
971 /* ************* */
972
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;
977         uint32_t period;
978 };
979
980 /* function called when cmd_monitor_period is parsed successfully */
981 static void cmd_monitor_period_parsed(void *parsed_result, void *data)
982 {
983         struct cmd_monitor_period_result *res = parsed_result;
984
985         if (res->period < 100) {
986                 printf_P(PSTR("error, minimum period is 100 ms\r\n"));
987                 return;
988         }
989
990         monitor_period_ms = res->period;
991 }
992
993 prog_char str_monitor_period[] = "period";
994
995 parse_pgm_token_string_t cmd_monitor_period_monitor_period =
996         TOKEN_STRING_INITIALIZER(struct cmd_monitor_period_result, monitor,
997                                  str_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);
1003
1004
1005 prog_char help_monitor_period[] = "set register monitoring period";
1006
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,
1015                 NULL,
1016         },
1017 };
1018
1019 /* ************* */
1020
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;
1026 };
1027
1028 /* function called when cmd_monitor_del is parsed successfully */
1029 static void cmd_monitor_del_parsed(void *parsed_result, void *data)
1030 {
1031         struct cmd_monitor_del_result *res = parsed_result;
1032
1033         monitor_current = LIST_NEXT(res->m, next);
1034         LIST_REMOVE(res->m, next);
1035         free(res->m);
1036         monitor_count --;
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;
1041                 return;
1042         }
1043 }
1044
1045 prog_char str_monitor_del[] = "del";
1046
1047 parse_pgm_token_string_t cmd_monitor_del_monitor_del =
1048         TOKEN_STRING_INITIALIZER(struct cmd_monitor_del_result, monitor,
1049                                  str_monitor);
1050 parse_pgm_token_string_t cmd_monitor_del_action =
1051         TOKEN_STRING_INITIALIZER(struct cmd_monitor_del_result, action,
1052                                  str_monitor_del);
1053 parse_pgm_token_monitor_t cmd_monitor_del_atcmd =
1054         TOKEN_MONITOR_INITIALIZER(struct cmd_monitor_del_result, m);
1055
1056
1057 prog_char help_monitor_del[] = "del a register in monitor list";
1058
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,
1067                 NULL,
1068         },
1069 };
1070
1071
1072 /* ************* */
1073
1074 /* this structure is filled when cmd_ping is parsed successfully */
1075 struct cmd_ping_result {
1076         fixed_string_t ping;
1077 };
1078
1079 /* function called when cmd_ping is parsed successfully */
1080 static void cmd_ping_parsed(void *parsed_result, void *data)
1081 {
1082         xbeeapp_send_atcmd("VL", NULL, 0, 1, NULL, NULL);
1083 }
1084
1085 prog_char str_ping[] = "ping";
1086
1087 parse_pgm_token_string_t cmd_ping_ping =
1088         TOKEN_STRING_INITIALIZER(struct cmd_ping_result, ping,
1089                                  str_ping);
1090
1091 prog_char help_ping[] = "Send a ping to the xbee device";
1092
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,
1099                 NULL,
1100         },
1101 };
1102
1103 /* ************* */
1104
1105 /* this structure is filled when cmd_raw is parsed successfully */
1106 struct cmd_raw_result {
1107         fixed_string_t raw;
1108 };
1109
1110 /* function called when cmd_raw is parsed successfully */
1111 static void cmd_raw_parsed(void *parsed_result, void *data)
1112 {
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 */
1115         xbee_raw = 1;
1116 }
1117
1118 prog_char str_raw[] = "raw";
1119
1120 parse_pgm_token_string_t cmd_raw_raw =
1121         TOKEN_STRING_INITIALIZER(struct cmd_raw_result, raw,
1122                                  str_raw);
1123
1124 prog_char help_raw[] = "Switch to raw mode";
1125
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,
1132                 NULL,
1133         },
1134 };
1135
1136 /* ************* */
1137
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;
1142 };
1143
1144 /* function called when cmd_dump is parsed successfully */
1145 static void cmd_dump_parsed(void *parsed_result, void *data)
1146 {
1147         struct cmd_dump_result *res = parsed_result;
1148         if (!strcmp(res->onoff, "on"))
1149                 xbee_hexdump = 1;
1150         else
1151                 xbee_hexdump = 0;
1152 }
1153
1154 prog_char str_dump[] = "dump";
1155 prog_char str_dump_onoff[] = "on#off";
1156
1157 parse_pgm_token_string_t cmd_dump_dump =
1158         TOKEN_STRING_INITIALIZER(struct cmd_dump_result, dump,
1159                                  str_dump);
1160
1161 parse_pgm_token_string_t cmd_dump_onoff =
1162         TOKEN_STRING_INITIALIZER(struct cmd_dump_result, onoff,
1163                                  str_dump_onoff);
1164
1165 prog_char help_dump[] = "enable/disable hexdump of received packets";
1166
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,
1174                 NULL,
1175         },
1176 };
1177
1178 /* ************* */
1179
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;
1184 };
1185
1186 /* function called when cmd_debug is parsed successfully */
1187 static void cmd_debug_parsed(void *parsed_result, void *data)
1188 {
1189         struct cmd_debug_result *res = parsed_result;
1190         if (!strcmp(res->onoff, "on"))
1191                 xbee_debug = 1;
1192         else
1193                 xbee_debug = 0;
1194 }
1195
1196 prog_char str_debug[] = "debug";
1197 prog_char str_debug_onoff[] = "on#off";
1198
1199 parse_pgm_token_string_t cmd_debug_debug =
1200         TOKEN_STRING_INITIALIZER(struct cmd_debug_result, debug,
1201                                  str_debug);
1202
1203 parse_pgm_token_string_t cmd_debug_onoff =
1204         TOKEN_STRING_INITIALIZER(struct cmd_debug_result, onoff,
1205                                  str_debug_onoff);
1206
1207 prog_char help_debug[] = "enable/disable additionnal debug";
1208
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,
1216                 NULL,
1217         },
1218 };
1219
1220 #ifndef USE_USB
1221 /**********************************************************/
1222
1223 /* this structure is filled when cmd_baudrate is parsed successfully */
1224 struct cmd_baudrate_result {
1225         fixed_string_t arg0;
1226         uint32_t arg1;
1227 };
1228
1229 /* function called when cmd_baudrate is parsed successfully */
1230 static void cmd_baudrate_parsed(void * parsed_result, __attribute__((unused)) void *data)
1231 {
1232         struct cmd_baudrate_result *res = parsed_result;
1233         struct uart_config c;
1234
1235         uart_getconf(XBEE_UART, &c);
1236         c.baudrate = res->arg1;
1237         uart_setconf(XBEE_UART, &c);
1238 }
1239
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,
1243                                  str_baudrate_arg0);
1244 parse_pgm_token_num_t cmd_baudrate_arg1 =
1245         TOKEN_NUM_INITIALIZER(struct cmd_baudrate_result, arg1,
1246                               UINT32);
1247
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,
1256                 NULL,
1257         },
1258 };
1259 #endif
1260
1261
1262 /* in progmem */
1263 parse_pgm_ctx_t main_ctx[] = {
1264
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,
1297 #ifndef USE_USB
1298         (parse_pgm_inst_t *)&cmd_baudrate,
1299 #endif
1300         NULL,
1301 };