add missing #ifndef to protect header files
[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 <aversive/wait.h>
33 #include <parse.h>
34 #include <rdline.h>
35 #include <parse_string.h>
36 #include <parse_num.h>
37 #include <uart.h>
38
39 #include "xbee_atcmd.h"
40 #include "xbee_neighbor.h"
41 #include "xbee_stats.h"
42 #include "xbee_proto.h"
43 #include "xbee.h"
44
45 #include "callout.h"
46 #include "parse_atcmd.h"
47 #include "parse_neighbor.h"
48 #include "parse_monitor.h"
49
50 #include "spi_servo.h"
51 #include "rc_proto.h"
52 #include "main.h"
53 #include "cmdline.h"
54
55 /* commands_gen.c */
56 extern const parse_inst_t PROGMEM cmd_reset;
57 extern const parse_inst_t PROGMEM cmd_bootloader;
58 extern const parse_inst_t PROGMEM cmd_log;
59 extern const parse_inst_t PROGMEM cmd_log_show;
60 extern const parse_inst_t PROGMEM cmd_log_type;
61 extern const parse_inst_t PROGMEM cmd_stack_space;
62 extern const parse_inst_t PROGMEM cmd_scheduler;
63
64 static int monitor_period_ms = 1000;
65 static int monitor_running = 0;
66 static int monitor_count = 0;
67 static struct callout monitor_event;
68 struct monitor_reg *monitor_current;
69
70 static int range_period_ms = 1000;
71 static int range_powermask = 0x1F;
72 static uint8_t range_power = 0;
73 static int range_running = 0;
74 static uint64_t range_dstaddr = 0xFFFF; /* broadcast by default */
75 static struct callout range_event;
76 static int range_count = 100;
77 static int range_cur_count = 0;
78
79 static void monitor_cb(struct callout_manager *cm,
80                        struct callout *clt, void *dummy)
81 {
82         (void)clt;
83         (void)dummy;
84
85         if (monitor_current == NULL)
86                 monitor_current = LIST_FIRST(&xbee_monitor_list);
87
88         xbeeapp_send_atcmd(monitor_current->atcmd, NULL, 0, 0, NULL, NULL);
89         monitor_current = LIST_NEXT(monitor_current, next);
90         callout_reset(cm, &monitor_event,
91                       monitor_period_ms / monitor_count,
92                       SINGLE, monitor_cb, NULL);
93 }
94
95 static void range_cb(struct callout_manager *cm,
96                      struct callout *clt, void *dummy)
97 {
98         uint8_t i, mask;
99         struct rc_proto_range rangepkt;
100
101         (void)clt;
102         (void)dummy;
103
104         range_cur_count--;
105
106         /* get new xmit power */
107         for (i = 1; i <= 8; i++) {
108                 mask = 1 << ((range_power + i) & 0x7);
109                 if (mask & range_powermask)
110                         break;
111         }
112         range_power = ((range_power + i) & 0x7);
113
114         xbeeapp_send_atcmd("PL", &range_power, sizeof(range_power), 0, NULL, NULL);
115
116         rangepkt.type = RC_PROTO_TYPE_RANGE;
117         rangepkt.power_level = range_power;
118
119         xbeeapp_send_msg(range_dstaddr, &rangepkt, sizeof(rangepkt), 0);
120
121         if (range_cur_count == 0) {
122                 range_running = 0;
123                 return;
124         }
125
126         callout_reset(cm, &range_event,
127                       range_period_ms,
128                       SINGLE, range_cb, NULL);
129 }
130
131 /* this structure is filled when cmd_help is parsed successfully */
132 struct cmd_help_result {
133         fixed_string_t help;
134         struct xbee_atcmd *cmd;
135 };
136
137 /* function called when cmd_help is parsed successfully */
138 static void cmd_help_parsed(void *parsed_result, void *data)
139 {
140         struct cmd_help_result *res = parsed_result;
141         struct xbee_atcmd cmdcopy;
142         int type;
143
144         (void)data;
145
146         memcpy_P(&cmdcopy, res->cmd, sizeof(cmdcopy));
147         type = (cmdcopy.flags & (XBEE_ATCMD_F_READ | XBEE_ATCMD_F_WRITE));
148         switch (type) {
149                 case XBEE_ATCMD_F_READ:
150                         printf_P(PSTR("Read-only\r\n"));
151                         break;
152                 case XBEE_ATCMD_F_WRITE:
153                         printf_P(PSTR("Write-only\r\n"));
154                         break;
155                 default:
156                         printf_P(PSTR("Read-write\r\n"));
157                         break;
158         }
159         if (cmdcopy.flags & XBEE_ATCMD_F_PARAM_NONE)
160                 printf_P(PSTR("No argument\r\n"));
161         else if (cmdcopy.flags & XBEE_ATCMD_F_PARAM_U8)
162                 printf_P(PSTR("Register is unsigned 8 bits\r\n"));
163         else if (cmdcopy.flags & XBEE_ATCMD_F_PARAM_U16)
164                 printf_P(PSTR("Register is unsigned 16 bits\r\n"));
165         else if (cmdcopy.flags & XBEE_ATCMD_F_PARAM_U32)
166                 printf_P(PSTR("Register is unsigned 32 bits\r\n"));
167         else if (cmdcopy.flags & XBEE_ATCMD_F_PARAM_S16)
168                 printf_P(PSTR("Register is signed 16 bits\r\n"));
169         else if (cmdcopy.flags & XBEE_ATCMD_F_PARAM_STRING_20B)
170                 printf_P(PSTR("Register is a 20 bytes string\r\n"));
171         else
172                 printf_P(PSTR("Unknown argument\r\n"));
173
174         printf_P(PSTR("%S\r\n"), cmdcopy.help);
175 }
176 const char PROGMEM str_help_help[] = "help";
177
178 const parse_token_string_t PROGMEM cmd_help_help =
179         TOKEN_STRING_INITIALIZER(struct cmd_help_result, help, str_help_help);
180
181 const parse_token_atcmd_t PROGMEM cmd_help_atcmd =
182         TOKEN_ATCMD_INITIALIZER(struct cmd_help_result, cmd, &xbee_dev,
183                                 0, 0);
184
185 const char PROGMEM help_help[] = "Help a register using an AT command";
186 const parse_inst_t PROGMEM cmd_help = {
187         .f = cmd_help_parsed,  /* function to call */
188         .data = NULL,      /* 2nd arg of func */
189         .help_str = help_help,
190         .tokens = {        /* token list, NULL terminated */
191                 (PGM_P)&cmd_help_help,
192                 (PGM_P)&cmd_help_atcmd,
193                 NULL,
194         },
195 };
196
197 /* ************* */
198
199 struct cmd_neigh_del_result {
200         fixed_string_t cmd;
201         fixed_string_t action;
202         struct xbee_neigh *neigh;
203 };
204
205 static void cmd_neigh_del_parsed(void *parsed_result,
206                                 void *data)
207 {
208         struct cmd_neigh_del_result *res = parsed_result;
209
210         (void)data;
211         xbee_neigh_del(xbee_dev, res->neigh);
212 }
213
214 const char PROGMEM str_neigh_del_neigh[] = "neigh";
215 const parse_token_string_t PROGMEM cmd_neigh_del_cmd =
216         TOKEN_STRING_INITIALIZER(struct cmd_neigh_del_result, cmd,
217                                  str_neigh_del_neigh);
218 const char PROGMEM str_neigh_del_del[] = "del";
219 const parse_token_string_t PROGMEM cmd_neigh_del_action =
220         TOKEN_STRING_INITIALIZER(struct cmd_neigh_del_result, action,
221                                  str_neigh_del_del);
222 const parse_token_neighbor_t PROGMEM cmd_neigh_del_neigh =
223         TOKEN_NEIGHBOR_INITIALIZER(struct cmd_neigh_del_result, neigh,
224                                    &xbee_dev);
225
226 const char PROGMEM help_neigh_del[] = "delete a neighbor";
227 const parse_inst_t PROGMEM cmd_neigh_del = {
228         .f = cmd_neigh_del_parsed,  /* function to call */
229         .data = NULL,      /* 2nd arg of func */
230         .help_str = help_neigh_del,
231         .tokens = {        /* token list, NULL terminated */
232                 (PGM_P)&cmd_neigh_del_cmd,
233                 (PGM_P)&cmd_neigh_del_action,
234                 (PGM_P)&cmd_neigh_del_neigh,
235                 NULL,
236         },
237 };
238
239 /* ************* */
240
241 struct cmd_neigh_add_result {
242         fixed_string_t cmd;
243         fixed_string_t action;
244         fixed_string_t name;
245         uint64_t addr;
246 };
247
248 static void cmd_neigh_add_parsed(void *parsed_result,
249                                  void *data)
250 {
251         struct cmd_neigh_add_result *res = parsed_result;
252
253         (void)data;
254         if (xbee_neigh_add(xbee_dev, res->name, res->addr) == NULL)
255                 printf_P(PSTR("name or addr already exist\r\n"));
256 }
257
258 const char PROGMEM str_neigh_add_neigh[] = "neigh";
259 const parse_token_string_t PROGMEM cmd_neigh_add_cmd =
260         TOKEN_STRING_INITIALIZER(struct cmd_neigh_add_result, cmd,
261                                  str_neigh_add_neigh);
262 const char PROGMEM str_neigh_add_add[] = "add";
263 const parse_token_string_t PROGMEM cmd_neigh_add_action =
264         TOKEN_STRING_INITIALIZER(struct cmd_neigh_add_result, action,
265                                  str_neigh_add_add);
266 const parse_token_string_t PROGMEM cmd_neigh_add_name =
267         TOKEN_STRING_INITIALIZER(struct cmd_neigh_add_result, name, NULL);
268 const parse_token_num_t PROGMEM cmd_neigh_add_addr =
269         TOKEN_NUM_INITIALIZER(struct cmd_neigh_add_result, addr, UINT64);
270
271 const char PROGMEM help_neigh_add[] = "add a neighbor";
272 const parse_inst_t PROGMEM cmd_neigh_add = {
273         .f = cmd_neigh_add_parsed,  /* function to call */
274         .data = NULL,      /* 2nd arg of func */
275         .help_str = help_neigh_add,
276         .tokens = {        /* token list, NULL terminated */
277                 (PGM_P)&cmd_neigh_add_cmd,
278                 (PGM_P)&cmd_neigh_add_action,
279                 (PGM_P)&cmd_neigh_add_name,
280                 (PGM_P)&cmd_neigh_add_addr,
281                 NULL,
282         },
283 };
284
285 /* ************* */
286
287 struct cmd_neigh_list_result {
288         fixed_string_t cmd;
289         fixed_string_t action;
290 };
291
292 static void cmd_neigh_list_parsed(void *parsed_result,
293                                 void *data)
294 {
295         struct xbee_neigh *neigh;
296
297         (void)parsed_result;
298         (void)data;
299         LIST_FOREACH(neigh, &xbee_dev->neigh_list, next) {
300                 printf_P(PSTR(" %s: 0x%.8"PRIx32"%.8"PRIx32"\r\n"),
301                          neigh->name,
302                          (uint32_t)(neigh->addr >> 32ULL),
303                          (uint32_t)(neigh->addr & 0xFFFFFFFF));
304         }
305 }
306
307 const char PROGMEM str_neigh_list_neigh[] = "neigh";
308 const parse_token_string_t PROGMEM cmd_neigh_list_cmd =
309         TOKEN_STRING_INITIALIZER(struct cmd_neigh_list_result, cmd,
310                                  str_neigh_list_neigh);
311 const char PROGMEM str_neigh_list_list[] = "list";
312 const parse_token_string_t PROGMEM cmd_neigh_list_action =
313         TOKEN_STRING_INITIALIZER(struct cmd_neigh_list_result, action,
314                                  str_neigh_list_list);
315
316 const char PROGMEM help_neigh_list[] = "list all knwon neighbors";
317 const parse_inst_t PROGMEM cmd_neigh_list = {
318         .f = cmd_neigh_list_parsed,  /* function to call */
319         .data = NULL,      /* 2nd arg of func */
320         .help_str = help_neigh_list,
321         .tokens = {        /* token list, NULL terminated */
322                 (PGM_P)&cmd_neigh_list_cmd,
323                 (PGM_P)&cmd_neigh_list_action,
324                 NULL,
325         },
326 };
327
328
329
330
331 /* ************* */
332
333 /* this structure is filled when cmd_read is parsed successfully */
334 struct cmd_read_result {
335         fixed_string_t read;
336         struct xbee_atcmd *cmd;
337 };
338
339 /* function called when cmd_read is parsed successfully */
340 static void cmd_read_parsed(void *parsed_result,
341                             void *data)
342 {
343         struct cmd_read_result *res = parsed_result;
344         struct xbee_atcmd copy;
345         char cmd[3];
346
347         (void)data;
348         memcpy_P(&copy, res->cmd, sizeof(copy));
349         memcpy_P(&cmd, copy.name, 2);
350         cmd[2] = '\0';
351         xbeeapp_send_atcmd(cmd, NULL, 0, 1, NULL, NULL);
352 }
353
354 const char PROGMEM str_read_read[] = "read";
355
356 const parse_token_string_t PROGMEM cmd_read_read =
357         TOKEN_STRING_INITIALIZER(struct cmd_read_result, read,
358                                  str_read_read);
359
360 const parse_token_atcmd_t PROGMEM cmd_read_atcmd =
361         TOKEN_ATCMD_INITIALIZER(struct cmd_read_result, cmd, &xbee_dev,
362                                 XBEE_ATCMD_F_READ, XBEE_ATCMD_F_READ);
363
364 const char PROGMEM help_read[] = "Read a register using an AT command";
365 const parse_inst_t PROGMEM cmd_read = {
366         .f = cmd_read_parsed,  /* function to call */
367         .data = NULL,      /* 2nd arg of func */
368         .help_str = help_read,
369         .tokens = {        /* token list, NULL terminated */
370                 (PGM_P)&cmd_read_read,
371                 (PGM_P)&cmd_read_atcmd,
372                 NULL,
373         },
374 };
375
376
377 /* ************* */
378
379 /* this structure is filled when cmd_write is parsed successfully */
380 struct cmd_write_result {
381         fixed_string_t write;
382         struct xbee_atcmd *cmd;
383         union {
384                 uint8_t u8;
385                 uint16_t u16;
386                 uint32_t u32;
387         };
388 };
389
390 /* function called when cmd_write is parsed successfully */
391 static void cmd_write_parsed(void *parsed_result, void *data)
392 {
393         struct cmd_write_result *res = parsed_result;
394         struct xbee_atcmd copy;
395         char cmd[3];
396         int len;
397         void *param;
398
399         (void)data;
400         memcpy_P(&copy, res->cmd, sizeof(copy));
401
402         if (copy.flags & XBEE_ATCMD_F_PARAM_NONE) {
403                 len = 0;
404                 param = NULL;
405         }
406         else if (copy.flags & XBEE_ATCMD_F_PARAM_U8) {
407                 len = sizeof(res->u8);
408                 param = &res->u8;
409         }
410         else if (copy.flags & XBEE_ATCMD_F_PARAM_U16) {
411                 len = sizeof(res->u16);
412                 res->u16 = htons(res->u16);
413                 param = &res->u16;
414         }
415         else if (copy.flags & XBEE_ATCMD_F_PARAM_U32) {
416                 len = sizeof(res->u32);
417                 res->u32 = htonl(res->u32);
418                 param = &res->u32;
419         }
420         else {
421                 printf_P(PSTR("Unknown argument type\r\n"));
422                 return;
423         }
424         memcpy_P(&cmd, copy.name, 2);
425         cmd[2] = '\0';
426         xbeeapp_send_atcmd(cmd, param, len, 1, NULL, NULL);
427 }
428
429 const char PROGMEM str_write_none[] = "write";
430
431 const parse_token_string_t PROGMEM cmd_write_write =
432         TOKEN_STRING_INITIALIZER(struct cmd_write_result, write,
433                                  str_write_none);
434
435 const parse_token_atcmd_t PROGMEM cmd_write_none_atcmd =
436         TOKEN_ATCMD_INITIALIZER(struct cmd_write_result, cmd,
437                                 &xbee_dev,
438                                 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_NONE,
439                                 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_NONE);
440
441 const char PROGMEM help_write_none[] = "Send an AT command (no argument)";
442
443 const parse_inst_t PROGMEM cmd_write_none = {
444         .f = cmd_write_parsed,  /* function to call */
445         .data = NULL,      /* 2nd arg of func */
446         .help_str = help_write_none,
447         .tokens = {        /* token list, NULL terminated */
448                 (PGM_P)&cmd_write_write,
449                 (PGM_P)&cmd_write_none_atcmd,
450                 NULL,
451         },
452 };
453
454 const parse_token_atcmd_t PROGMEM cmd_write_u8_atcmd =
455         TOKEN_ATCMD_INITIALIZER(struct cmd_write_result, cmd,
456                                 &xbee_dev,
457                                 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U8,
458                                 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U8);
459
460 const parse_token_num_t PROGMEM cmd_write_u8_u8 =
461         TOKEN_NUM_INITIALIZER(struct cmd_write_result, u8, UINT8);
462
463 const char PROGMEM help_write_u8[] = "Write a 8 bits register using an AT command";
464
465 const parse_inst_t PROGMEM cmd_write_u8 = {
466         .f = cmd_write_parsed,  /* function to call */
467         .data = NULL,      /* 2nd arg of func */
468         .help_str = help_write_u8,
469         .tokens = {        /* token list, NULL terminated */
470                 (PGM_P)&cmd_write_write,
471                 (PGM_P)&cmd_write_u8_atcmd,
472                 (PGM_P)&cmd_write_u8_u8,
473                 NULL,
474         },
475 };
476
477 const parse_token_atcmd_t PROGMEM cmd_write_u16_atcmd =
478         TOKEN_ATCMD_INITIALIZER(struct cmd_write_result, cmd,
479                                 &xbee_dev,
480                                 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U16,
481                                 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U16);
482
483 const parse_token_num_t PROGMEM cmd_write_u16_u16 =
484         TOKEN_NUM_INITIALIZER(struct cmd_write_result, u16, UINT16);
485
486 const char PROGMEM help_write_u16[] = "Write a 16 bits register using an AT command";
487
488 const parse_inst_t PROGMEM cmd_write_u16 = {
489         .f = cmd_write_parsed,  /* function to call */
490         .data = NULL,      /* 2nd arg of func */
491         .help_str = help_write_u16,
492         .tokens = {        /* token list, NULL terminated */
493                 (PGM_P)&cmd_write_write,
494                 (PGM_P)&cmd_write_u16_atcmd,
495                 (PGM_P)&cmd_write_u16_u16,
496                 NULL,
497         },
498 };
499
500 const parse_token_atcmd_t PROGMEM cmd_write_u32_atcmd =
501         TOKEN_ATCMD_INITIALIZER(struct cmd_write_result, cmd,
502                                 &xbee_dev,
503                                 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U32,
504                                 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U32);
505
506 const parse_token_num_t PROGMEM cmd_write_u32_u32 =
507         TOKEN_NUM_INITIALIZER(struct cmd_write_result, u32, UINT32);
508
509 const char PROGMEM help_write_u32[] = "Write a 32 bits register using an AT command";
510
511 const parse_inst_t PROGMEM cmd_write_u32 = {
512         .f = cmd_write_parsed,  /* function to call */
513         .data = NULL,      /* 2nd arg of func */
514         .help_str = help_write_u32,
515         .tokens = {        /* token list, NULL terminated */
516                 (PGM_P)&cmd_write_write,
517                 (PGM_P)&cmd_write_u32_atcmd,
518                 (PGM_P)&cmd_write_u32_u32,
519                 NULL,
520         },
521 };
522
523
524 /* ************* */
525
526 /* this structure is filled when cmd_sendmsg is parsed successfully */
527 struct cmd_sendmsg_result {
528         fixed_string_t sendmsg;
529         uint64_t addr;
530         fixed_string_t data;
531 };
532
533 /* function called when cmd_sendmsg is parsed successfully */
534 static void cmd_sendmsg_parsed(void *parsed_result, void *data)
535 {
536         struct cmd_sendmsg_result *res = parsed_result;
537
538         (void)data;
539         xbeeapp_send_msg(res->addr, res->data, strlen(res->data), 1);
540 }
541
542 const char PROGMEM str_sendmsg[] = "sendmsg";
543
544 const parse_token_string_t PROGMEM cmd_sendmsg_sendmsg =
545         TOKEN_STRING_INITIALIZER(struct cmd_sendmsg_result, sendmsg,
546                                  str_sendmsg);
547
548 const parse_token_num_t PROGMEM cmd_sendmsg_addr =
549         TOKEN_NUM_INITIALIZER(struct cmd_sendmsg_result, addr, UINT64);
550
551 const parse_token_string_t PROGMEM cmd_sendmsg_data =
552         TOKEN_STRING_INITIALIZER(struct cmd_sendmsg_result, data, NULL);
553
554 const char PROGMEM help_sendmsg[] = "Send data to a node using its address";
555
556 const parse_inst_t PROGMEM cmd_sendmsg = {
557         .f = cmd_sendmsg_parsed,  /* function to call */
558         .data = NULL,      /* 2nd arg of func */
559         .help_str = help_sendmsg,
560         .tokens = {        /* token list, NULL terminated */
561                 (PGM_P)&cmd_sendmsg_sendmsg,
562                 (PGM_P)&cmd_sendmsg_addr,
563                 (PGM_P)&cmd_sendmsg_data,
564                 NULL,
565         },
566 };
567
568 /* ************* */
569
570 /* this structure is filled when cmd_sendmsg_name is parsed successfully */
571 struct cmd_sendmsg_name_result {
572         fixed_string_t sendmsg_name;
573         struct xbee_neigh *neigh;
574         fixed_string_t data;
575 };
576
577 /* function called when cmd_sendmsg_name is parsed successfully */
578 static void cmd_sendmsg_name_parsed(void *parsed_result, void *data)
579 {
580         struct cmd_sendmsg_name_result *res = parsed_result;
581
582         (void)data;
583         xbeeapp_send_msg(res->neigh->addr, res->data, strlen(res->data), 1);
584 }
585
586 const parse_token_string_t PROGMEM cmd_sendmsg_name_sendmsg_name =
587         TOKEN_STRING_INITIALIZER(struct cmd_sendmsg_name_result, sendmsg_name,
588                                  str_sendmsg);
589
590 const parse_token_neighbor_t PROGMEM cmd_sendmsg_name_neigh =
591         TOKEN_NEIGHBOR_INITIALIZER(struct cmd_sendmsg_name_result, neigh,
592                                    &xbee_dev);
593
594 const parse_token_string_t PROGMEM cmd_sendmsg_name_data =
595         TOKEN_STRING_INITIALIZER(struct cmd_sendmsg_name_result, data, NULL);
596
597 const char PROGMEM help_sendmsg_name[] = "Send data to a node using its name";
598
599 const parse_inst_t PROGMEM cmd_sendmsg_name = {
600         .f = cmd_sendmsg_name_parsed,  /* function to call */
601         .data = NULL,      /* 2nd arg of func */
602         .help_str = help_sendmsg_name,
603         .tokens = {        /* token list, NULL terminated */
604                 (PGM_P)&cmd_sendmsg_name_sendmsg_name,
605                 (PGM_P)&cmd_sendmsg_name_neigh,
606                 (PGM_P)&cmd_sendmsg_name_data,
607                 NULL,
608         },
609 };
610
611
612 /* ************* */
613
614 /* this structure is filled when cmd_range is parsed successfully */
615 struct cmd_range_result {
616         fixed_string_t range;
617         fixed_string_t action;
618 };
619
620 /* function called when cmd_range is parsed successfully */
621 static void cmd_range_parsed(void *parsed_result, void *data)
622 {
623         struct cmd_range_result *res = parsed_result;
624
625         (void)data;
626         if (!strcmp_P(res->action, PSTR("show"))) {
627                 printf_P(PSTR("range infos:\r\n"));
628                 printf_P(PSTR("  range period %d\r\n"), range_period_ms);
629                 printf_P(PSTR("  range count %d\r\n"), range_count);
630                 printf_P(PSTR("  range powermask 0x%x\r\n"), range_powermask);
631                 printf_P(PSTR("  range dstaddr 0x%.8"PRIx32"%.8"PRIx32"\r\n"),
632                          (uint32_t)(range_dstaddr >> 32ULL),
633                          (uint32_t)(range_dstaddr & 0xFFFFFFFF));
634
635                 if (range_running)
636                         printf_P(PSTR("  range test is running\r\n"));
637                 else
638                         printf_P(PSTR("  range test is not running\r\n"));
639         }
640         else if (!strcmp(res->action, "start")) {
641                 if (range_running) {
642                         printf_P(PSTR("already running\r\n"));
643                         return;
644                 }
645                 range_cur_count = range_count;
646                 callout_init(&range_event);
647                 callout_reset(&cm, &range_event, 0,
648                               SINGLE, range_cb, NULL);
649                 range_running = 1;
650         }
651         else if (!strcmp(res->action, "end")) {
652                 if (range_running == 0) {
653                         printf_P(PSTR("not running\r\n"));
654                         return;
655                 }
656                 range_running = 0;
657                 callout_stop(&cm, &range_event);
658         }
659 }
660
661 const char PROGMEM str_range[] = "range";
662 const char PROGMEM str_range_tokens[] = "show#start#end";
663
664 const parse_token_string_t PROGMEM cmd_range_range =
665         TOKEN_STRING_INITIALIZER(struct cmd_range_result, range,
666                                  str_range);
667 const parse_token_string_t PROGMEM cmd_range_action =
668         TOKEN_STRING_INITIALIZER(struct cmd_range_result, action,
669                                  str_range_tokens);
670
671 const char PROGMEM help_range[] = "start/stop/show current rangeing";
672
673 const parse_inst_t PROGMEM cmd_range = {
674         .f = cmd_range_parsed,  /* function to call */
675         .data = NULL,      /* 2nd arg of func */
676         .help_str = help_range,
677         .tokens = {        /* token list, NULL terminated */
678                 (PGM_P)&cmd_range_range,
679                 (PGM_P)&cmd_range_action,
680                 NULL,
681         },
682 };
683
684 /* ************* */
685
686 /* this structure is filled when cmd_range_period is parsed successfully */
687 struct cmd_range_period_result {
688         fixed_string_t range;
689         fixed_string_t action;
690         uint32_t period;
691 };
692
693 /* function called when cmd_range_period is parsed successfully */
694 static void cmd_range_period_parsed(void *parsed_result, void *data)
695 {
696         struct cmd_range_period_result *res = parsed_result;
697
698         (void)data;
699         if (res->period < 10) {
700                 printf_P(PSTR("error, minimum period is 10 ms\r\n"));
701                 return;
702         }
703
704         range_period_ms = res->period;
705 }
706
707 const char PROGMEM str_period[] = "period";
708
709 const parse_token_string_t PROGMEM cmd_range_period_range_period =
710         TOKEN_STRING_INITIALIZER(struct cmd_range_period_result, range,
711                                  str_range);
712 const parse_token_string_t PROGMEM cmd_range_period_action =
713         TOKEN_STRING_INITIALIZER(struct cmd_range_period_result, action,
714                                  str_period);
715 const parse_token_num_t PROGMEM cmd_range_period_period =
716         TOKEN_NUM_INITIALIZER(struct cmd_range_period_result, period, UINT32);
717
718 const char PROGMEM help_range_period[] = "set range test period";
719
720 const parse_inst_t PROGMEM cmd_range_period = {
721         .f = cmd_range_period_parsed,  /* function to call */
722         .data = NULL,      /* 2nd arg of func */
723         .help_str = help_range_period,
724         .tokens = {        /* token list, NULL terminated */
725                 (PGM_P)&cmd_range_period_range_period,
726                 (PGM_P)&cmd_range_period_action,
727                 (PGM_P)&cmd_range_period_period,
728                 NULL,
729         },
730 };
731
732 /* ************* */
733
734 /* this structure is filled when cmd_range_count is parsed successfully */
735 struct cmd_range_count_result {
736         fixed_string_t range;
737         fixed_string_t action;
738         uint32_t count;
739 };
740
741 /* function called when cmd_range_count is parsed successfully */
742 static void cmd_range_count_parsed(void *parsed_result, void *data)
743 {
744         struct cmd_range_count_result *res = parsed_result;
745
746         (void)data;
747         range_count = res->count;
748 }
749
750 const char PROGMEM str_count[] = "count";
751
752 const parse_token_string_t PROGMEM cmd_range_count_range_count =
753         TOKEN_STRING_INITIALIZER(struct cmd_range_count_result, range,
754                                  str_range);
755 const parse_token_string_t PROGMEM cmd_range_count_action =
756         TOKEN_STRING_INITIALIZER(struct cmd_range_count_result, action,
757                                  str_count);
758 const parse_token_num_t PROGMEM cmd_range_count_count =
759         TOKEN_NUM_INITIALIZER(struct cmd_range_count_result, count, UINT32);
760
761
762 const char PROGMEM help_range_count[] = "set range test count";
763
764 const parse_inst_t PROGMEM cmd_range_count = {
765         .f = cmd_range_count_parsed,  /* function to call */
766         .data = NULL,      /* 2nd arg of func */
767         .help_str = help_range_count,
768         .tokens = {        /* token list, NULL terminated */
769                 (PGM_P)&cmd_range_count_range_count,
770                 (PGM_P)&cmd_range_count_action,
771                 (PGM_P)&cmd_range_count_count,
772                 NULL,
773         },
774 };
775
776 /* ************* */
777
778 /* this structure is filled when cmd_range_powermask is parsed successfully */
779 struct cmd_range_powermask_result {
780         fixed_string_t range;
781         fixed_string_t action;
782         uint8_t powermask;
783 };
784
785 /* function called when cmd_range_powermask is parsed successfully */
786 static void cmd_range_powermask_parsed(void *parsed_result, void *data)
787 {
788         struct cmd_range_powermask_result *res = parsed_result;
789
790         (void)data;
791         range_powermask = res->powermask;
792 }
793
794 const char PROGMEM str_powermask[] = "powermask";
795
796 const parse_token_string_t PROGMEM cmd_range_powermask_range_powermask =
797         TOKEN_STRING_INITIALIZER(struct cmd_range_powermask_result, range,
798                                  str_range);
799 const parse_token_string_t PROGMEM cmd_range_powermask_action =
800         TOKEN_STRING_INITIALIZER(struct cmd_range_powermask_result, action,
801                                  str_powermask);
802 const parse_token_num_t PROGMEM cmd_range_powermask_powermask =
803         TOKEN_NUM_INITIALIZER(struct cmd_range_powermask_result, powermask,
804                               UINT8);
805
806
807 const char PROGMEM help_range_powermask[] = "set range test powermask";
808
809 const parse_inst_t PROGMEM cmd_range_powermask = {
810         .f = cmd_range_powermask_parsed,  /* function to call */
811         .data = NULL,      /* 2nd arg of func */
812         .help_str = help_range_powermask,
813         .tokens = {        /* token list, NULL terminated */
814                 (PGM_P)&cmd_range_powermask_range_powermask,
815                 (PGM_P)&cmd_range_powermask_action,
816                 (PGM_P)&cmd_range_powermask_powermask,
817                 NULL,
818         },
819 };
820
821 /* ************* */
822
823 /* this structure is filled when cmd_range_dstaddr is parsed successfully */
824 struct cmd_range_dstaddr_result {
825         fixed_string_t range;
826         fixed_string_t action;
827         uint64_t dstaddr;
828 };
829
830 /* function called when cmd_range_dstaddr is parsed successfully */
831 static void cmd_range_dstaddr_parsed(void *parsed_result, void *data)
832 {
833         struct cmd_range_dstaddr_result *res = parsed_result;
834
835         (void)data;
836         range_dstaddr = res->dstaddr;
837 }
838
839 const char PROGMEM str_dstaddr[] = "dstaddr";
840
841 const parse_token_string_t PROGMEM cmd_range_dstaddr_range_dstaddr =
842         TOKEN_STRING_INITIALIZER(struct cmd_range_dstaddr_result, range,
843                                  str_range);
844 const parse_token_string_t PROGMEM cmd_range_dstaddr_action =
845         TOKEN_STRING_INITIALIZER(struct cmd_range_dstaddr_result, action,
846                                  str_dstaddr);
847 const parse_token_num_t PROGMEM cmd_range_dstaddr_dstaddr =
848         TOKEN_NUM_INITIALIZER(struct cmd_range_dstaddr_result, dstaddr, UINT64);
849
850
851 const char PROGMEM help_range_dstaddr[] = "set register rangeing dstaddr";
852
853 const parse_inst_t PROGMEM cmd_range_dstaddr = {
854         .f = cmd_range_dstaddr_parsed,  /* function to call */
855         .data = NULL,      /* 2nd arg of func */
856         .help_str = help_range_dstaddr,
857         .tokens = {        /* token list, NULL terminated */
858                 (PGM_P)&cmd_range_dstaddr_range_dstaddr,
859                 (PGM_P)&cmd_range_dstaddr_action,
860                 (PGM_P)&cmd_range_dstaddr_dstaddr,
861                 NULL,
862         },
863 };
864
865
866 /* ************* */
867
868 /* this structure is filled when cmd_monitor is parsed successfully */
869 struct cmd_monitor_result {
870         fixed_string_t monitor;
871         fixed_string_t action;
872 };
873
874 /* function called when cmd_monitor is parsed successfully */
875 static void cmd_monitor_parsed(void *parsed_result, void *data)
876 {
877         struct cmd_monitor_result *res = parsed_result;
878         struct monitor_reg *m;
879
880         (void)data;
881         if (!strcmp_P(res->action, PSTR("show"))) {
882                 printf_P(PSTR("monitor period is %d ms, %d regs in list\r\n"),
883                        monitor_period_ms, monitor_count);
884                 LIST_FOREACH(m, &xbee_monitor_list, next)
885                         printf_P(PSTR(" %S\r\n"), m->desc);
886         }
887         else if (!strcmp_P(res->action, PSTR("start"))) {
888                 if (monitor_running) {
889                         printf_P(PSTR("already running\r\n"));
890                         return;
891                 }
892                 if (monitor_count == 0) {
893                         printf_P(PSTR("no regs to be monitored\r\n"));
894                         return;
895                 }
896                 callout_init(&monitor_event);
897                 callout_reset(&cm, &monitor_event, 0, SINGLE, monitor_cb, NULL);
898                 monitor_running = 1;
899                 monitor_current = LIST_FIRST(&xbee_monitor_list);
900                 printf_P(PSTR("monitor cb: %S %s\r\n"),
901                          monitor_current->desc,
902                          monitor_current->atcmd);
903
904         }
905         else if (!strcmp_P(res->action, PSTR("end"))) {
906                 if (monitor_running == 0) {
907                         printf_P(PSTR("not running\r\n"));
908                         return;
909                 }
910                 monitor_running = 0;
911                 callout_stop(&cm, &monitor_event);
912         }
913 }
914
915 const char PROGMEM str_monitor[] = "monitor";
916 const char PROGMEM str_monitor_tokens[] = "show#start#end";
917
918 const parse_token_string_t PROGMEM cmd_monitor_monitor =
919         TOKEN_STRING_INITIALIZER(struct cmd_monitor_result, monitor,
920                                  str_monitor);
921 const parse_token_string_t PROGMEM cmd_monitor_action =
922         TOKEN_STRING_INITIALIZER(struct cmd_monitor_result, action,
923                                  str_monitor_tokens);
924
925 const char PROGMEM help_monitor[] = "start/stop/show current monitoring";
926
927 const parse_inst_t PROGMEM cmd_monitor = {
928         .f = cmd_monitor_parsed,  /* function to call */
929         .data = NULL,      /* 2nd arg of func */
930         .help_str = help_monitor,
931         .tokens = {        /* token list, NULL terminated */
932                 (PGM_P)&cmd_monitor_monitor,
933                 (PGM_P)&cmd_monitor_action,
934                 NULL,
935         },
936 };
937
938 /* ************* */
939
940 /* this structure is filled when cmd_monitor_add is parsed successfully */
941 struct cmd_monitor_add_result {
942         fixed_string_t monitor;
943         fixed_string_t action;
944         struct xbee_atcmd *cmd;
945 };
946
947 /* function called when cmd_monitor_add is parsed successfully */
948 static void cmd_monitor_add_parsed(void *parsed_result, void *data)
949 {
950         struct cmd_monitor_add_result *res = parsed_result;
951         struct monitor_reg *m;
952         struct xbee_atcmd copy;
953
954         (void)data;
955         memcpy_P(&copy, res->cmd, sizeof(copy));
956         LIST_FOREACH(m, &xbee_monitor_list, next) {
957                 if (!strcmp_P(m->atcmd, copy.name))
958                         break;
959         }
960
961         if (m != NULL) {
962                 printf_P(PSTR("already exist\r\n"));
963                 return;
964         }
965
966         m = malloc(sizeof(*m));
967         if (m == NULL) {
968                 printf_P(PSTR("no mem\r\n"));
969                 return;
970         }
971         m->desc = copy.desc;
972         strcpy_P(m->atcmd, copy.name);
973         LIST_INSERT_HEAD(&xbee_monitor_list, m, next);
974         monitor_count ++;
975 }
976
977 const char PROGMEM str_monitor_add[] = "add";
978
979 const parse_token_string_t PROGMEM cmd_monitor_add_monitor_add =
980         TOKEN_STRING_INITIALIZER(struct cmd_monitor_add_result, monitor,
981                                  str_monitor);
982 const parse_token_string_t PROGMEM cmd_monitor_add_action =
983         TOKEN_STRING_INITIALIZER(struct cmd_monitor_add_result, action,
984                                  str_monitor_add);
985 const parse_token_atcmd_t PROGMEM cmd_monitor_add_atcmd =
986         TOKEN_ATCMD_INITIALIZER(struct cmd_monitor_add_result, cmd, &xbee_dev,
987                                 XBEE_ATCMD_F_READ, XBEE_ATCMD_F_READ);
988
989
990 const char PROGMEM help_monitor_add[] = "add a register in monitor list";
991
992 const parse_inst_t PROGMEM cmd_monitor_add = {
993         .f = cmd_monitor_add_parsed,  /* function to call */
994         .data = NULL,      /* 2nd arg of func */
995         .help_str = help_monitor_add,
996         .tokens = {        /* token list, NULL terminated */
997                 (PGM_P)&cmd_monitor_add_monitor_add,
998                 (PGM_P)&cmd_monitor_add_action,
999                 (PGM_P)&cmd_monitor_add_atcmd,
1000                 NULL,
1001         },
1002 };
1003
1004 /* ************* */
1005
1006 /* this structure is filled when cmd_monitor_period is parsed successfully */
1007 struct cmd_monitor_period_result {
1008         fixed_string_t monitor;
1009         fixed_string_t action;
1010         uint32_t period;
1011 };
1012
1013 /* function called when cmd_monitor_period is parsed successfully */
1014 static void cmd_monitor_period_parsed(void *parsed_result, void *data)
1015 {
1016         struct cmd_monitor_period_result *res = parsed_result;
1017
1018         (void)data;
1019         if (res->period < 100) {
1020                 printf_P(PSTR("error, minimum period is 100 ms\r\n"));
1021                 return;
1022         }
1023
1024         monitor_period_ms = res->period;
1025 }
1026
1027 const char PROGMEM str_monitor_period[] = "period";
1028
1029 const parse_token_string_t PROGMEM cmd_monitor_period_monitor_period =
1030         TOKEN_STRING_INITIALIZER(struct cmd_monitor_period_result, monitor,
1031                                  str_monitor);
1032 const parse_token_string_t PROGMEM cmd_monitor_period_action =
1033         TOKEN_STRING_INITIALIZER(struct cmd_monitor_period_result, action,
1034                                  str_monitor_period);
1035 const parse_token_num_t PROGMEM cmd_monitor_period_period =
1036         TOKEN_NUM_INITIALIZER(struct cmd_monitor_period_result, period, UINT32);
1037
1038
1039 const char PROGMEM help_monitor_period[] = "set register monitoring period";
1040
1041 const parse_inst_t PROGMEM cmd_monitor_period = {
1042         .f = cmd_monitor_period_parsed,  /* function to call */
1043         .data = NULL,      /* 2nd arg of func */
1044         .help_str = help_monitor_period,
1045         .tokens = {        /* token list, NULL terminated */
1046                 (PGM_P)&cmd_monitor_period_monitor_period,
1047                 (PGM_P)&cmd_monitor_period_action,
1048                 (PGM_P)&cmd_monitor_period_period,
1049                 NULL,
1050         },
1051 };
1052
1053 /* ************* */
1054
1055 /* this structure is filled when cmd_monitor_del is parsed successfully */
1056 struct cmd_monitor_del_result {
1057         fixed_string_t monitor;
1058         fixed_string_t action;
1059         struct monitor_reg *m;
1060 };
1061
1062 /* function called when cmd_monitor_del is parsed successfully */
1063 static void cmd_monitor_del_parsed(void *parsed_result, void *data)
1064 {
1065         struct cmd_monitor_del_result *res = parsed_result;
1066
1067         (void)data;
1068         monitor_current = LIST_NEXT(res->m, next);
1069         LIST_REMOVE(res->m, next);
1070         free(res->m);
1071         monitor_count --;
1072         if (monitor_count == 0) {
1073                 printf_P(PSTR("Disable monitoring, no more event\r\n"));
1074                 callout_stop(&cm, &monitor_event);
1075                 monitor_running = 0;
1076                 return;
1077         }
1078 }
1079
1080 const char PROGMEM str_monitor_del[] = "del";
1081
1082 const parse_token_string_t PROGMEM cmd_monitor_del_monitor_del =
1083         TOKEN_STRING_INITIALIZER(struct cmd_monitor_del_result, monitor,
1084                                  str_monitor);
1085 const parse_token_string_t PROGMEM cmd_monitor_del_action =
1086         TOKEN_STRING_INITIALIZER(struct cmd_monitor_del_result, action,
1087                                  str_monitor_del);
1088 const parse_token_monitor_t PROGMEM cmd_monitor_del_atcmd =
1089         TOKEN_MONITOR_INITIALIZER(struct cmd_monitor_del_result, m);
1090
1091
1092 const char PROGMEM help_monitor_del[] = "del a register in monitor list";
1093
1094 const parse_inst_t PROGMEM cmd_monitor_del = {
1095         .f = cmd_monitor_del_parsed,  /* function to call */
1096         .data = NULL,      /* 2nd arg of func */
1097         .help_str = help_monitor_del,
1098         .tokens = {        /* token list, NULL terminated */
1099                 (PGM_P)&cmd_monitor_del_monitor_del,
1100                 (PGM_P)&cmd_monitor_del_action,
1101                 (PGM_P)&cmd_monitor_del_atcmd,
1102                 NULL,
1103         },
1104 };
1105
1106
1107 /* ************* */
1108
1109 /* this structure is filled when cmd_ping is parsed successfully */
1110 struct cmd_ping_result {
1111         fixed_string_t ping;
1112 };
1113
1114 /* function called when cmd_ping is parsed successfully */
1115 static void cmd_ping_parsed(void *parsed_result, void *data)
1116 {
1117         (void)parsed_result;
1118         (void)data;
1119         xbeeapp_send_atcmd("VL", NULL, 0, 1, NULL, NULL);
1120 }
1121
1122 const char PROGMEM str_ping[] = "ping";
1123
1124 const parse_token_string_t PROGMEM cmd_ping_ping =
1125         TOKEN_STRING_INITIALIZER(struct cmd_ping_result, ping,
1126                                  str_ping);
1127
1128 const char PROGMEM help_ping[] = "Send a ping to the xbee device";
1129
1130 const parse_inst_t PROGMEM cmd_ping = {
1131         .f = cmd_ping_parsed,  /* function to call */
1132         .data = NULL,      /* 2nd arg of func */
1133         .help_str = help_ping,
1134         .tokens = {        /* token list, NULL terminated */
1135                 (PGM_P)&cmd_ping_ping,
1136                 NULL,
1137         },
1138 };
1139
1140 /* ************* */
1141
1142 /* this structure is filled when cmd_raw is parsed successfully */
1143 struct cmd_raw_result {
1144         fixed_string_t raw;
1145 };
1146
1147 /* function called when cmd_raw is parsed successfully */
1148 static void cmd_raw_parsed(void *parsed_result, void *data)
1149 {
1150         (void)parsed_result;
1151         (void)data;
1152         printf_P(PSTR("switched to raw mode, CTRL-D to exit\r\n"));
1153         rdline_stop(&xbeeboard.rdl); /* don't display prompt when return */
1154         xbee_raw = 1;
1155 }
1156
1157 const char PROGMEM str_raw[] = "raw";
1158
1159 const parse_token_string_t PROGMEM cmd_raw_raw =
1160         TOKEN_STRING_INITIALIZER(struct cmd_raw_result, raw,
1161                                  str_raw);
1162
1163 const char PROGMEM help_raw[] = "Switch to raw mode";
1164
1165 const parse_inst_t PROGMEM cmd_raw = {
1166         .f = cmd_raw_parsed,  /* function to call */
1167         .data = NULL,      /* 2nd arg of func */
1168         .help_str = help_raw,
1169         .tokens = {        /* token list, NULL terminated */
1170                 (PGM_P)&cmd_raw_raw,
1171                 NULL,
1172         },
1173 };
1174
1175 /* ************* */
1176
1177 /* this structure is filled when cmd_dump is parsed successfully */
1178 struct cmd_dump_result {
1179         fixed_string_t dump;
1180         fixed_string_t onoff;
1181 };
1182
1183 /* function called when cmd_dump is parsed successfully */
1184 static void cmd_dump_parsed(void *parsed_result, void *data)
1185 {
1186         struct cmd_dump_result *res = parsed_result;
1187
1188         (void)data;
1189         if (!strcmp(res->onoff, "on"))
1190                 xbee_hexdump = 1;
1191         else
1192                 xbee_hexdump = 0;
1193 }
1194
1195 const char PROGMEM str_dump[] = "dump";
1196 const char PROGMEM str_dump_onoff[] = "on#off";
1197
1198 const parse_token_string_t PROGMEM cmd_dump_dump =
1199         TOKEN_STRING_INITIALIZER(struct cmd_dump_result, dump,
1200                                  str_dump);
1201
1202 const parse_token_string_t PROGMEM cmd_dump_onoff =
1203         TOKEN_STRING_INITIALIZER(struct cmd_dump_result, onoff,
1204                                  str_dump_onoff);
1205
1206 const char PROGMEM help_dump[] = "enable/disable hexdump of received packets";
1207
1208 const parse_inst_t PROGMEM cmd_dump = {
1209         .f = cmd_dump_parsed,  /* function to call */
1210         .data = NULL,      /* 2nd arg of func */
1211         .help_str = help_dump,
1212         .tokens = {        /* token list, NULL terminated */
1213                 (PGM_P)&cmd_dump_dump,
1214                 (PGM_P)&cmd_dump_onoff,
1215                 NULL,
1216         },
1217 };
1218
1219 /* ************* */
1220
1221 /* this structure is filled when cmd_debug is parsed successfully */
1222 struct cmd_debug_result {
1223         fixed_string_t debug;
1224         fixed_string_t onoff;
1225 };
1226
1227 /* function called when cmd_debug is parsed successfully */
1228 static void cmd_debug_parsed(void *parsed_result, void *data)
1229 {
1230         struct cmd_debug_result *res = parsed_result;
1231
1232         (void)data;
1233         if (!strcmp(res->onoff, "on"))
1234                 xbee_debug = 1;
1235         else
1236                 xbee_debug = 0;
1237 }
1238
1239 const char PROGMEM str_debug[] = "debug";
1240 const char PROGMEM str_debug_onoff[] = "on#off";
1241
1242 const parse_token_string_t PROGMEM cmd_debug_debug =
1243         TOKEN_STRING_INITIALIZER(struct cmd_debug_result, debug,
1244                                  str_debug);
1245
1246 const parse_token_string_t PROGMEM cmd_debug_onoff =
1247         TOKEN_STRING_INITIALIZER(struct cmd_debug_result, onoff,
1248                                  str_debug_onoff);
1249
1250 const char PROGMEM help_debug[] = "enable/disable additionnal debug";
1251
1252 const parse_inst_t PROGMEM cmd_debug = {
1253         .f = cmd_debug_parsed,  /* function to call */
1254         .data = NULL,      /* 2nd arg of func */
1255         .help_str = help_debug,
1256         .tokens = {        /* token list, NULL terminated */
1257                 (PGM_P)&cmd_debug_debug,
1258                 (PGM_P)&cmd_debug_onoff,
1259                 NULL,
1260         },
1261 };
1262
1263 /**********************************************************/
1264
1265 /* this structure is filled when cmd_baudrate is parsed successfully */
1266 struct cmd_baudrate_result {
1267         fixed_string_t arg0;
1268         uint32_t arg1;
1269 };
1270
1271 /* function called when cmd_baudrate is parsed successfully */
1272 static void cmd_baudrate_parsed(void * parsed_result, __attribute__((unused)) void *data)
1273 {
1274         struct cmd_baudrate_result *res = parsed_result;
1275         struct uart_config c;
1276
1277         uart_getconf(XBEE_UART, &c);
1278         c.baudrate = res->arg1;
1279         uart_setconf(XBEE_UART, &c);
1280 }
1281
1282 const char PROGMEM str_baudrate_arg0[] = "baudrate";
1283 const parse_token_string_t PROGMEM cmd_baudrate_arg0 =
1284         TOKEN_STRING_INITIALIZER(struct cmd_baudrate_result, arg0,
1285                                  str_baudrate_arg0);
1286 const parse_token_num_t PROGMEM cmd_baudrate_arg1 =
1287         TOKEN_NUM_INITIALIZER(struct cmd_baudrate_result, arg1,
1288                               UINT32);
1289
1290 const char PROGMEM help_baudrate[] = "Change xbee baudrate";
1291 const parse_inst_t PROGMEM cmd_baudrate = {
1292         .f = cmd_baudrate_parsed,  /* function to call */
1293         .data = NULL,      /* 2nd arg of func */
1294         .help_str = help_baudrate,
1295         .tokens = {        /* token list, NULL terminated */
1296                 (PGM_P)&cmd_baudrate_arg0,
1297                 (PGM_P)&cmd_baudrate_arg1,
1298                 NULL,
1299         },
1300 };
1301
1302 /* this structure is filled when cmd_test_spi is parsed successfully */
1303 struct cmd_test_spi_result {
1304         fixed_string_t arg0;
1305 };
1306
1307 static void cmd_test_spi_parsed(void * parsed_result, void *data)
1308 {
1309         int i;
1310
1311         (void)parsed_result;
1312         (void)data;
1313
1314         while (1) {
1315                 for (i = 0; i < 50; i++) {
1316                         spi_servo_set(0, 0);
1317                         wait_ms(100);
1318                         spi_servo_set(0, 500);
1319                         wait_ms(100);
1320                 }
1321
1322                 spi_servo_bypass(1);
1323                 wait_ms(10000);
1324                 spi_servo_bypass(0);
1325                 wait_ms(1);
1326         }
1327 }
1328
1329 const char PROGMEM str_test_spi_arg0[] = "test_spi";
1330 const parse_token_string_t PROGMEM cmd_test_spi_arg0 =
1331         TOKEN_STRING_INITIALIZER(struct cmd_test_spi_result, arg0,
1332                                  str_test_spi_arg0);
1333
1334 const char PROGMEM help_test_spi[] = "Test the spi";
1335 const parse_inst_t PROGMEM cmd_test_spi = {
1336         .f = cmd_test_spi_parsed,  /* function to call */
1337         .data = NULL,      /* 2nd arg of func */
1338         .help_str = help_test_spi,
1339         .tokens = {        /* token list, NULL terminated */
1340                 (PGM_P)&cmd_test_spi_arg0,
1341                 NULL,
1342         },
1343 };
1344
1345 /* in progmem */
1346 const parse_ctx_t PROGMEM main_ctx[] = {
1347
1348         /* commands_gen.c */
1349         &cmd_reset,
1350         &cmd_bootloader,
1351         &cmd_log,
1352         &cmd_log_show,
1353         &cmd_log_type,
1354         &cmd_stack_space,
1355         &cmd_scheduler,
1356         &cmd_help,
1357         &cmd_neigh_del,
1358         &cmd_neigh_add,
1359         &cmd_neigh_list,
1360         &cmd_read,
1361         &cmd_write_none,
1362         &cmd_write_u8,
1363         &cmd_write_u16,
1364         &cmd_write_u32,
1365         &cmd_sendmsg,
1366         &cmd_sendmsg_name,
1367         &cmd_range,
1368         &cmd_range_period,
1369         &cmd_range_count,
1370         &cmd_range_powermask,
1371         &cmd_range_dstaddr,
1372         &cmd_monitor,
1373         &cmd_monitor_period,
1374         &cmd_monitor_add,
1375         &cmd_monitor_del,
1376         &cmd_ping,
1377         &cmd_raw,
1378         &cmd_dump,
1379         &cmd_debug,
1380         &cmd_baudrate,
1381         &cmd_test_spi,
1382         NULL,
1383 };