use callout instead of scheduler
[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 #include <xbee.h>
39
40 #include "callout.h"
41 #include "parse_atcmd.h"
42 #include "parse_neighbor.h"
43 #include "parse_monitor.h"
44
45 #include "spi_servo.h"
46 #include "rc_proto.h"
47 #include "main.h"
48 #include "cmdline.h"
49 #include "beep.h"
50 #include "eeprom_config.h"
51
52 /* commands_gen.c */
53 extern const parse_inst_t PROGMEM cmd_reset;
54 extern const parse_inst_t PROGMEM cmd_bootloader;
55 extern const parse_inst_t PROGMEM cmd_log;
56 extern const parse_inst_t PROGMEM cmd_log_show;
57 extern const parse_inst_t PROGMEM cmd_log_type;
58 extern const parse_inst_t PROGMEM cmd_stack_space;
59 extern const parse_inst_t PROGMEM cmd_callout;
60
61 static int monitor_period_ms = 1000;
62 static int monitor_running = 0;
63 static int monitor_count = 0;
64 static struct callout monitor_event;
65 struct monitor_reg *monitor_current;
66
67 static int range_period_ms = 1000;
68 static int range_powermask = 0x1F;
69 //static uint8_t range_power = 0;
70 static int range_running = 0;
71 static uint64_t range_dstaddr = 0xFFFF; /* broadcast by default */
72 static struct callout range_event;
73 static int range_count = 100;
74 static int range_cur_count = 0;
75
76 static void monitor_cb(struct callout_mgr *cm,
77                        struct callout *clt, void *dummy)
78 {
79         (void)clt;
80         (void)dummy;
81
82         if (monitor_current == NULL)
83                 monitor_current = LIST_FIRST(&xbee_monitor_list);
84
85         xbeeapp_send_atcmd(monitor_current->atcmd, NULL, 0, 0, NULL, NULL);
86         monitor_current = LIST_NEXT(monitor_current, next);
87         callout_reschedule(cm, clt, monitor_period_ms / monitor_count);
88 }
89
90 static void range_cb(struct callout_mgr *cm,
91                      struct callout *clt, void *dummy)
92 {
93         (void)cm;
94         (void)clt;
95         (void)dummy;
96 #if 0
97         uint8_t i, mask;
98         struct rc_proto_range rangepkt;
99
100         (void)clt;
101         (void)dummy;
102
103         range_cur_count--;
104
105         /* get new xmit power */
106         for (i = 1; i <= 8; i++) {
107                 mask = 1 << ((range_power + i) & 0x7);
108                 if (mask & range_powermask)
109                         break;
110         }
111         range_power = ((range_power + i) & 0x7);
112
113         xbeeapp_send_atcmd("PL", &range_power, sizeof(range_power), 0, NULL, NULL);
114
115         rangepkt.type = RC_PROTO_TYPE_RANGE;
116         rangepkt.power_level = range_power;
117
118         xbeeapp_send_msg(range_dstaddr, &rangepkt, sizeof(rangepkt), 0);
119
120         if (range_cur_count == 0) {
121                 range_running = 0;
122                 callout_stop(cm, clt);
123         }
124
125         callout_reschedule(cm, clt, range_period_ms);
126 #endif
127 }
128
129 /* this structure is filled when cmd_help is parsed successfully */
130 struct cmd_help_result {
131         fixed_string_t help;
132         struct xbee_atcmd *cmd;
133 };
134
135 /* function called when cmd_help is parsed successfully */
136 static void cmd_help_parsed(void *parsed_result, void *data)
137 {
138         struct cmd_help_result *res = parsed_result;
139         struct xbee_atcmd cmdcopy;
140         int type;
141
142         (void)data;
143
144         memcpy_P(&cmdcopy, res->cmd, sizeof(cmdcopy));
145         type = (cmdcopy.flags & (XBEE_ATCMD_F_READ | XBEE_ATCMD_F_WRITE));
146         switch (type) {
147                 case XBEE_ATCMD_F_READ:
148                         printf_P(PSTR("Read-only\r\n"));
149                         break;
150                 case XBEE_ATCMD_F_WRITE:
151                         printf_P(PSTR("Write-only\r\n"));
152                         break;
153                 default:
154                         printf_P(PSTR("Read-write\r\n"));
155                         break;
156         }
157         if (cmdcopy.flags & XBEE_ATCMD_F_PARAM_NONE)
158                 printf_P(PSTR("No argument\r\n"));
159         else if (cmdcopy.flags & XBEE_ATCMD_F_PARAM_U8)
160                 printf_P(PSTR("Register is unsigned 8 bits\r\n"));
161         else if (cmdcopy.flags & XBEE_ATCMD_F_PARAM_U16)
162                 printf_P(PSTR("Register is unsigned 16 bits\r\n"));
163         else if (cmdcopy.flags & XBEE_ATCMD_F_PARAM_U32)
164                 printf_P(PSTR("Register is unsigned 32 bits\r\n"));
165         else if (cmdcopy.flags & XBEE_ATCMD_F_PARAM_S16)
166                 printf_P(PSTR("Register is signed 16 bits\r\n"));
167         else if (cmdcopy.flags & XBEE_ATCMD_F_PARAM_STRING_20B)
168                 printf_P(PSTR("Register is a 20 bytes string\r\n"));
169         else
170                 printf_P(PSTR("Unknown argument\r\n"));
171
172         printf_P(PSTR("%S\r\n"), cmdcopy.help);
173 }
174 const char PROGMEM str_help_help[] = "help";
175
176 const parse_token_string_t PROGMEM cmd_help_help =
177         TOKEN_STRING_INITIALIZER(struct cmd_help_result, help, str_help_help);
178
179 const parse_token_atcmd_t PROGMEM cmd_help_atcmd =
180         TOKEN_ATCMD_INITIALIZER(struct cmd_help_result, cmd, &xbee_dev,
181                                 0, 0);
182
183 const char PROGMEM help_help[] = "Help a register using an AT command";
184 const parse_inst_t PROGMEM cmd_help = {
185         .f = cmd_help_parsed,  /* function to call */
186         .data = NULL,      /* 2nd arg of func */
187         .help_str = help_help,
188         .tokens = {        /* token list, NULL terminated */
189                 (PGM_P)&cmd_help_help,
190                 (PGM_P)&cmd_help_atcmd,
191                 NULL,
192         },
193 };
194
195 /* ************* */
196
197 struct cmd_neigh_del_result {
198         fixed_string_t cmd;
199         fixed_string_t action;
200         struct xbee_neigh *neigh;
201 };
202
203 static void cmd_neigh_del_parsed(void *parsed_result,
204                                 void *data)
205 {
206         struct cmd_neigh_del_result *res = parsed_result;
207
208         (void)data;
209         xbee_neigh_del(xbee_dev, res->neigh);
210 }
211
212 const char PROGMEM str_neigh_del_neigh[] = "neigh";
213 const parse_token_string_t PROGMEM cmd_neigh_del_cmd =
214         TOKEN_STRING_INITIALIZER(struct cmd_neigh_del_result, cmd,
215                                  str_neigh_del_neigh);
216 const char PROGMEM str_neigh_del_del[] = "del";
217 const parse_token_string_t PROGMEM cmd_neigh_del_action =
218         TOKEN_STRING_INITIALIZER(struct cmd_neigh_del_result, action,
219                                  str_neigh_del_del);
220 const parse_token_neighbor_t PROGMEM cmd_neigh_del_neigh =
221         TOKEN_NEIGHBOR_INITIALIZER(struct cmd_neigh_del_result, neigh,
222                                    &xbee_dev);
223
224 const char PROGMEM help_neigh_del[] = "delete a neighbor";
225 const parse_inst_t PROGMEM cmd_neigh_del = {
226         .f = cmd_neigh_del_parsed,  /* function to call */
227         .data = NULL,      /* 2nd arg of func */
228         .help_str = help_neigh_del,
229         .tokens = {        /* token list, NULL terminated */
230                 (PGM_P)&cmd_neigh_del_cmd,
231                 (PGM_P)&cmd_neigh_del_action,
232                 (PGM_P)&cmd_neigh_del_neigh,
233                 NULL,
234         },
235 };
236
237 /* ************* */
238
239 struct cmd_neigh_add_result {
240         fixed_string_t cmd;
241         fixed_string_t action;
242         fixed_string_t name;
243         uint64_t addr;
244 };
245
246 static void cmd_neigh_add_parsed(void *parsed_result,
247                                  void *data)
248 {
249         struct cmd_neigh_add_result *res = parsed_result;
250
251         (void)data;
252         if (xbee_neigh_add(xbee_dev, res->name, res->addr) == NULL)
253                 printf_P(PSTR("name or addr already exist\r\n"));
254 }
255
256 const char PROGMEM str_neigh_add_neigh[] = "neigh";
257 const parse_token_string_t PROGMEM cmd_neigh_add_cmd =
258         TOKEN_STRING_INITIALIZER(struct cmd_neigh_add_result, cmd,
259                                  str_neigh_add_neigh);
260 const char PROGMEM str_neigh_add_add[] = "add";
261 const parse_token_string_t PROGMEM cmd_neigh_add_action =
262         TOKEN_STRING_INITIALIZER(struct cmd_neigh_add_result, action,
263                                  str_neigh_add_add);
264 const parse_token_string_t PROGMEM cmd_neigh_add_name =
265         TOKEN_STRING_INITIALIZER(struct cmd_neigh_add_result, name, NULL);
266 const parse_token_num_t PROGMEM cmd_neigh_add_addr =
267         TOKEN_NUM_INITIALIZER(struct cmd_neigh_add_result, addr, UINT64);
268
269 const char PROGMEM help_neigh_add[] = "add a neighbor";
270 const parse_inst_t PROGMEM cmd_neigh_add = {
271         .f = cmd_neigh_add_parsed,  /* function to call */
272         .data = NULL,      /* 2nd arg of func */
273         .help_str = help_neigh_add,
274         .tokens = {        /* token list, NULL terminated */
275                 (PGM_P)&cmd_neigh_add_cmd,
276                 (PGM_P)&cmd_neigh_add_action,
277                 (PGM_P)&cmd_neigh_add_name,
278                 (PGM_P)&cmd_neigh_add_addr,
279                 NULL,
280         },
281 };
282
283 /* ************* */
284
285 struct cmd_neigh_list_result {
286         fixed_string_t cmd;
287         fixed_string_t action;
288 };
289
290 static void cmd_neigh_list_parsed(void *parsed_result,
291                                 void *data)
292 {
293         struct xbee_neigh *neigh;
294
295         (void)parsed_result;
296         (void)data;
297         LIST_FOREACH(neigh, &xbee_dev->neigh_list, next) {
298                 printf_P(PSTR(" %s: 0x%.8"PRIx32"%.8"PRIx32"\r\n"),
299                          neigh->name,
300                          (uint32_t)(neigh->addr >> 32ULL),
301                          (uint32_t)(neigh->addr & 0xFFFFFFFF));
302         }
303 }
304
305 const char PROGMEM str_neigh_list_neigh[] = "neigh";
306 const parse_token_string_t PROGMEM cmd_neigh_list_cmd =
307         TOKEN_STRING_INITIALIZER(struct cmd_neigh_list_result, cmd,
308                                  str_neigh_list_neigh);
309 const char PROGMEM str_neigh_list_list[] = "list";
310 const parse_token_string_t PROGMEM cmd_neigh_list_action =
311         TOKEN_STRING_INITIALIZER(struct cmd_neigh_list_result, action,
312                                  str_neigh_list_list);
313
314 const char PROGMEM help_neigh_list[] = "list all knwon neighbors";
315 const parse_inst_t PROGMEM cmd_neigh_list = {
316         .f = cmd_neigh_list_parsed,  /* function to call */
317         .data = NULL,      /* 2nd arg of func */
318         .help_str = help_neigh_list,
319         .tokens = {        /* token list, NULL terminated */
320                 (PGM_P)&cmd_neigh_list_cmd,
321                 (PGM_P)&cmd_neigh_list_action,
322                 NULL,
323         },
324 };
325
326
327
328
329 /* ************* */
330
331 /* this structure is filled when cmd_read is parsed successfully */
332 struct cmd_read_result {
333         fixed_string_t read;
334         struct xbee_atcmd *cmd;
335 };
336
337 /* function called when cmd_read is parsed successfully */
338 static void cmd_read_parsed(void *parsed_result,
339                             void *data)
340 {
341         struct cmd_read_result *res = parsed_result;
342         struct xbee_atcmd copy;
343         char cmd[3];
344
345         (void)data;
346         memcpy_P(&copy, res->cmd, sizeof(copy));
347         memcpy_P(&cmd, copy.name, 2);
348         cmd[2] = '\0';
349         xbeeapp_send_atcmd(cmd, NULL, 0, 1, NULL, NULL);
350 }
351
352 const char PROGMEM str_read_read[] = "read";
353
354 const parse_token_string_t PROGMEM cmd_read_read =
355         TOKEN_STRING_INITIALIZER(struct cmd_read_result, read,
356                                  str_read_read);
357
358 const parse_token_atcmd_t PROGMEM cmd_read_atcmd =
359         TOKEN_ATCMD_INITIALIZER(struct cmd_read_result, cmd, &xbee_dev,
360                                 XBEE_ATCMD_F_READ, XBEE_ATCMD_F_READ);
361
362 const char PROGMEM help_read[] = "Read a register using an AT command";
363 const parse_inst_t PROGMEM cmd_read = {
364         .f = cmd_read_parsed,  /* function to call */
365         .data = NULL,      /* 2nd arg of func */
366         .help_str = help_read,
367         .tokens = {        /* token list, NULL terminated */
368                 (PGM_P)&cmd_read_read,
369                 (PGM_P)&cmd_read_atcmd,
370                 NULL,
371         },
372 };
373
374
375 /* ************* */
376
377 /* this structure is filled when cmd_write is parsed successfully */
378 struct cmd_write_result {
379         fixed_string_t write;
380         struct xbee_atcmd *cmd;
381         union {
382                 uint8_t u8;
383                 uint16_t u16;
384                 uint32_t u32;
385         };
386 };
387
388 /* function called when cmd_write is parsed successfully */
389 static void cmd_write_parsed(void *parsed_result, void *data)
390 {
391         struct cmd_write_result *res = parsed_result;
392         struct xbee_atcmd copy;
393         char cmd[3];
394         int len;
395         void *param;
396
397         (void)data;
398         memcpy_P(&copy, res->cmd, sizeof(copy));
399
400         if (copy.flags & XBEE_ATCMD_F_PARAM_NONE) {
401                 len = 0;
402                 param = NULL;
403         }
404         else if (copy.flags & XBEE_ATCMD_F_PARAM_U8) {
405                 len = sizeof(res->u8);
406                 param = &res->u8;
407         }
408         else if (copy.flags & XBEE_ATCMD_F_PARAM_U16) {
409                 len = sizeof(res->u16);
410                 res->u16 = htons(res->u16);
411                 param = &res->u16;
412         }
413         else if (copy.flags & XBEE_ATCMD_F_PARAM_U32) {
414                 len = sizeof(res->u32);
415                 res->u32 = htonl(res->u32);
416                 param = &res->u32;
417         }
418         else {
419                 printf_P(PSTR("Unknown argument type\r\n"));
420                 return;
421         }
422         memcpy_P(&cmd, copy.name, 2);
423         cmd[2] = '\0';
424         xbeeapp_send_atcmd(cmd, param, len, 1, NULL, NULL);
425 }
426
427 const char PROGMEM str_write_none[] = "write";
428
429 const parse_token_string_t PROGMEM cmd_write_write =
430         TOKEN_STRING_INITIALIZER(struct cmd_write_result, write,
431                                  str_write_none);
432
433 const parse_token_atcmd_t PROGMEM cmd_write_none_atcmd =
434         TOKEN_ATCMD_INITIALIZER(struct cmd_write_result, cmd,
435                                 &xbee_dev,
436                                 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_NONE,
437                                 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_NONE);
438
439 const char PROGMEM help_write_none[] = "Send an AT command (no argument)";
440
441 const parse_inst_t PROGMEM cmd_write_none = {
442         .f = cmd_write_parsed,  /* function to call */
443         .data = NULL,      /* 2nd arg of func */
444         .help_str = help_write_none,
445         .tokens = {        /* token list, NULL terminated */
446                 (PGM_P)&cmd_write_write,
447                 (PGM_P)&cmd_write_none_atcmd,
448                 NULL,
449         },
450 };
451
452 const parse_token_atcmd_t PROGMEM cmd_write_u8_atcmd =
453         TOKEN_ATCMD_INITIALIZER(struct cmd_write_result, cmd,
454                                 &xbee_dev,
455                                 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U8,
456                                 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U8);
457
458 const parse_token_num_t PROGMEM cmd_write_u8_u8 =
459         TOKEN_NUM_INITIALIZER(struct cmd_write_result, u8, UINT8);
460
461 const char PROGMEM help_write_u8[] = "Write a 8 bits register using an AT command";
462
463 const parse_inst_t PROGMEM cmd_write_u8 = {
464         .f = cmd_write_parsed,  /* function to call */
465         .data = NULL,      /* 2nd arg of func */
466         .help_str = help_write_u8,
467         .tokens = {        /* token list, NULL terminated */
468                 (PGM_P)&cmd_write_write,
469                 (PGM_P)&cmd_write_u8_atcmd,
470                 (PGM_P)&cmd_write_u8_u8,
471                 NULL,
472         },
473 };
474
475 const parse_token_atcmd_t PROGMEM cmd_write_u16_atcmd =
476         TOKEN_ATCMD_INITIALIZER(struct cmd_write_result, cmd,
477                                 &xbee_dev,
478                                 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U16,
479                                 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U16);
480
481 const parse_token_num_t PROGMEM cmd_write_u16_u16 =
482         TOKEN_NUM_INITIALIZER(struct cmd_write_result, u16, UINT16);
483
484 const char PROGMEM help_write_u16[] = "Write a 16 bits register using an AT command";
485
486 const parse_inst_t PROGMEM cmd_write_u16 = {
487         .f = cmd_write_parsed,  /* function to call */
488         .data = NULL,      /* 2nd arg of func */
489         .help_str = help_write_u16,
490         .tokens = {        /* token list, NULL terminated */
491                 (PGM_P)&cmd_write_write,
492                 (PGM_P)&cmd_write_u16_atcmd,
493                 (PGM_P)&cmd_write_u16_u16,
494                 NULL,
495         },
496 };
497
498 const parse_token_atcmd_t PROGMEM cmd_write_u32_atcmd =
499         TOKEN_ATCMD_INITIALIZER(struct cmd_write_result, cmd,
500                                 &xbee_dev,
501                                 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U32,
502                                 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U32);
503
504 const parse_token_num_t PROGMEM cmd_write_u32_u32 =
505         TOKEN_NUM_INITIALIZER(struct cmd_write_result, u32, UINT32);
506
507 const char PROGMEM help_write_u32[] = "Write a 32 bits register using an AT command";
508
509 const parse_inst_t PROGMEM cmd_write_u32 = {
510         .f = cmd_write_parsed,  /* function to call */
511         .data = NULL,      /* 2nd arg of func */
512         .help_str = help_write_u32,
513         .tokens = {        /* token list, NULL terminated */
514                 (PGM_P)&cmd_write_write,
515                 (PGM_P)&cmd_write_u32_atcmd,
516                 (PGM_P)&cmd_write_u32_u32,
517                 NULL,
518         },
519 };
520
521
522 /* ************* */
523
524 /* this structure is filled when cmd_sendmsg is parsed successfully */
525 struct cmd_sendmsg_result {
526         fixed_string_t sendmsg;
527         uint64_t addr;
528         fixed_string_t data;
529 };
530
531 /* function called when cmd_sendmsg is parsed successfully */
532 static void cmd_sendmsg_parsed(void *parsed_result, void *data)
533 {
534         struct cmd_sendmsg_result *res = parsed_result;
535
536         (void)data;
537         xbeeapp_send_msg(res->addr, res->data, strlen(res->data), 1);
538 }
539
540 const char PROGMEM str_sendmsg[] = "sendmsg";
541
542 const parse_token_string_t PROGMEM cmd_sendmsg_sendmsg =
543         TOKEN_STRING_INITIALIZER(struct cmd_sendmsg_result, sendmsg,
544                                  str_sendmsg);
545
546 const parse_token_num_t PROGMEM cmd_sendmsg_addr =
547         TOKEN_NUM_INITIALIZER(struct cmd_sendmsg_result, addr, UINT64);
548
549 const parse_token_string_t PROGMEM cmd_sendmsg_data =
550         TOKEN_STRING_INITIALIZER(struct cmd_sendmsg_result, data, NULL);
551
552 const char PROGMEM help_sendmsg[] = "Send data to a node using its address";
553
554 const parse_inst_t PROGMEM cmd_sendmsg = {
555         .f = cmd_sendmsg_parsed,  /* function to call */
556         .data = NULL,      /* 2nd arg of func */
557         .help_str = help_sendmsg,
558         .tokens = {        /* token list, NULL terminated */
559                 (PGM_P)&cmd_sendmsg_sendmsg,
560                 (PGM_P)&cmd_sendmsg_addr,
561                 (PGM_P)&cmd_sendmsg_data,
562                 NULL,
563         },
564 };
565
566 /* ************* */
567
568 /* this structure is filled when cmd_send_hello is parsed successfully */
569 struct cmd_send_hello_result {
570         fixed_string_t send_hello;
571         uint64_t addr;
572         struct xbee_neigh *neigh;
573         uint16_t period;
574         uint16_t count;
575         fixed_string_t data;
576 };
577
578 /* function called when cmd_send_hello is parsed successfully */
579 static void cmd_send_hello_parsed(void *parsed_result, void *use_neigh)
580 {
581         struct cmd_send_hello_result *res = parsed_result;
582         uint16_t now, next, diff;
583         uint8_t flags;
584         uint64_t addr;
585
586         if (use_neigh)
587                 addr = res->neigh->addr;
588         else
589                 addr = res->addr;
590
591         IRQ_LOCK(flags);
592         now = global_ms;
593         IRQ_UNLOCK(flags);
594
595         next = now;
596
597         while (!cmdline_keypressed() && res->count != 0) {
598                 IRQ_LOCK(flags);
599                 now = global_ms;
600                 IRQ_UNLOCK(flags);
601
602                 diff = now - next;
603                 if (diff < res->period)
604                         continue;
605
606                 rc_proto_send_hello(addr, res->data, strlen(res->data));
607                 next += res->period;
608                 res->count--;
609         }
610 }
611
612 const char PROGMEM str_send_hello[] = "send_hello";
613
614 const parse_token_string_t PROGMEM cmd_send_hello_send_hello =
615         TOKEN_STRING_INITIALIZER(struct cmd_send_hello_result, send_hello,
616                                  str_send_hello);
617
618 const parse_token_num_t PROGMEM cmd_send_hello_addr =
619         TOKEN_NUM_INITIALIZER(struct cmd_send_hello_result, addr, UINT64);
620
621 const parse_token_num_t PROGMEM cmd_send_hello_period =
622         TOKEN_NUM_INITIALIZER(struct cmd_send_hello_result, period, UINT16);
623
624 const parse_token_num_t PROGMEM cmd_send_hello_count =
625         TOKEN_NUM_INITIALIZER(struct cmd_send_hello_result, count, UINT16);
626
627 const parse_token_string_t PROGMEM cmd_send_hello_data =
628         TOKEN_STRING_INITIALIZER(struct cmd_send_hello_result, data, NULL);
629
630 const char PROGMEM help_send_hello[] =
631         "Send hello msg to a node: addr, period_ms, count, str";
632
633 const parse_inst_t PROGMEM cmd_send_hello = {
634         .f = cmd_send_hello_parsed,  /* function to call */
635         .data = NULL,      /* 2nd arg of func */
636         .help_str = help_send_hello,
637         .tokens = {        /* token list, NULL terminated */
638                 (PGM_P)&cmd_send_hello_send_hello,
639                 (PGM_P)&cmd_send_hello_addr,
640                 (PGM_P)&cmd_send_hello_period,
641                 (PGM_P)&cmd_send_hello_count,
642                 (PGM_P)&cmd_send_hello_data,
643                 NULL,
644         },
645 };
646
647 const parse_token_neighbor_t PROGMEM cmd_send_hello_neigh =
648         TOKEN_NEIGHBOR_INITIALIZER(struct cmd_send_hello_result, neigh,
649                                    &xbee_dev);
650
651 const parse_inst_t PROGMEM cmd_send_hello_name = {
652         .f = cmd_send_hello_parsed,  /* function to call */
653         .data = (void *)1,      /* 2nd arg of func */
654         .help_str = help_send_hello,
655         .tokens = {        /* token list, NULL terminated */
656                 (PGM_P)&cmd_send_hello_send_hello,
657                 (PGM_P)&cmd_send_hello_neigh,
658                 (PGM_P)&cmd_send_hello_period,
659                 (PGM_P)&cmd_send_hello_count,
660                 (PGM_P)&cmd_send_hello_data,
661                 NULL,
662         },
663 };
664
665 /* ************* */
666
667 /* this structure is filled when cmd_sendmsg_name is parsed successfully */
668 struct cmd_sendmsg_name_result {
669         fixed_string_t sendmsg_name;
670         struct xbee_neigh *neigh;
671         fixed_string_t data;
672 };
673
674 /* function called when cmd_sendmsg_name is parsed successfully */
675 static void cmd_sendmsg_name_parsed(void *parsed_result, void *data)
676 {
677         struct cmd_sendmsg_name_result *res = parsed_result;
678
679         (void)data;
680         xbeeapp_send_msg(res->neigh->addr, res->data, strlen(res->data), 1);
681 }
682
683 const parse_token_string_t PROGMEM cmd_sendmsg_name_sendmsg_name =
684         TOKEN_STRING_INITIALIZER(struct cmd_sendmsg_name_result, sendmsg_name,
685                                  str_sendmsg);
686
687 const parse_token_neighbor_t PROGMEM cmd_sendmsg_name_neigh =
688         TOKEN_NEIGHBOR_INITIALIZER(struct cmd_sendmsg_name_result, neigh,
689                                    &xbee_dev);
690
691 const parse_token_string_t PROGMEM cmd_sendmsg_name_data =
692         TOKEN_STRING_INITIALIZER(struct cmd_sendmsg_name_result, data, NULL);
693
694 const char PROGMEM help_sendmsg_name[] = "Send data to a node using its name";
695
696 const parse_inst_t PROGMEM cmd_sendmsg_name = {
697         .f = cmd_sendmsg_name_parsed,  /* function to call */
698         .data = NULL,      /* 2nd arg of func */
699         .help_str = help_sendmsg_name,
700         .tokens = {        /* token list, NULL terminated */
701                 (PGM_P)&cmd_sendmsg_name_sendmsg_name,
702                 (PGM_P)&cmd_sendmsg_name_neigh,
703                 (PGM_P)&cmd_sendmsg_name_data,
704                 NULL,
705         },
706 };
707
708
709 /* ************* */
710
711 /* this structure is filled when cmd_range is parsed successfully */
712 struct cmd_range_result {
713         fixed_string_t range;
714         fixed_string_t action;
715 };
716
717 /* function called when cmd_range is parsed successfully */
718 static void cmd_range_parsed(void *parsed_result, void *data)
719 {
720         struct cmd_range_result *res = parsed_result;
721
722         (void)data;
723         if (!strcmp_P(res->action, PSTR("show"))) {
724                 printf_P(PSTR("range infos:\r\n"));
725                 printf_P(PSTR("  range period %d\r\n"), range_period_ms);
726                 printf_P(PSTR("  range count %d\r\n"), range_count);
727                 printf_P(PSTR("  range powermask 0x%x\r\n"), range_powermask);
728                 printf_P(PSTR("  range dstaddr 0x%.8"PRIx32"%.8"PRIx32"\r\n"),
729                          (uint32_t)(range_dstaddr >> 32ULL),
730                          (uint32_t)(range_dstaddr & 0xFFFFFFFF));
731
732                 if (range_running)
733                         printf_P(PSTR("  range test is running\r\n"));
734                 else
735                         printf_P(PSTR("  range test is not running\r\n"));
736         }
737         else if (!strcmp(res->action, "start")) {
738                 if (range_running) {
739                         printf_P(PSTR("already running\r\n"));
740                         return;
741                 }
742                 range_cur_count = range_count;
743                 callout_init(&range_event, range_cb, NULL, 0);
744                 callout_schedule(&xbeeboard.mainloop_cm,
745                         &range_event, 0); /* immediate */
746                 range_running = 1;
747         }
748         else if (!strcmp(res->action, "end")) {
749                 if (range_running == 0) {
750                         printf_P(PSTR("not running\r\n"));
751                         return;
752                 }
753                 range_running = 0;
754                 callout_stop(&xbeeboard.mainloop_cm, &range_event);
755         }
756 }
757
758 const char PROGMEM str_range[] = "range";
759 const char PROGMEM str_range_tokens[] = "show#start#end";
760
761 const parse_token_string_t PROGMEM cmd_range_range =
762         TOKEN_STRING_INITIALIZER(struct cmd_range_result, range,
763                                  str_range);
764 const parse_token_string_t PROGMEM cmd_range_action =
765         TOKEN_STRING_INITIALIZER(struct cmd_range_result, action,
766                                  str_range_tokens);
767
768 const char PROGMEM help_range[] = "start/stop/show current rangeing";
769
770 const parse_inst_t PROGMEM cmd_range = {
771         .f = cmd_range_parsed,  /* function to call */
772         .data = NULL,      /* 2nd arg of func */
773         .help_str = help_range,
774         .tokens = {        /* token list, NULL terminated */
775                 (PGM_P)&cmd_range_range,
776                 (PGM_P)&cmd_range_action,
777                 NULL,
778         },
779 };
780
781 /* ************* */
782
783 /* this structure is filled when cmd_range_period is parsed successfully */
784 struct cmd_range_period_result {
785         fixed_string_t range;
786         fixed_string_t action;
787         uint32_t period;
788 };
789
790 /* function called when cmd_range_period is parsed successfully */
791 static void cmd_range_period_parsed(void *parsed_result, void *data)
792 {
793         struct cmd_range_period_result *res = parsed_result;
794
795         (void)data;
796         if (res->period < 10) {
797                 printf_P(PSTR("error, minimum period is 10 ms\r\n"));
798                 return;
799         }
800
801         range_period_ms = res->period;
802 }
803
804 const char PROGMEM str_period[] = "period";
805
806 const parse_token_string_t PROGMEM cmd_range_period_range_period =
807         TOKEN_STRING_INITIALIZER(struct cmd_range_period_result, range,
808                                  str_range);
809 const parse_token_string_t PROGMEM cmd_range_period_action =
810         TOKEN_STRING_INITIALIZER(struct cmd_range_period_result, action,
811                                  str_period);
812 const parse_token_num_t PROGMEM cmd_range_period_period =
813         TOKEN_NUM_INITIALIZER(struct cmd_range_period_result, period, UINT32);
814
815 const char PROGMEM help_range_period[] = "set range test period";
816
817 const parse_inst_t PROGMEM cmd_range_period = {
818         .f = cmd_range_period_parsed,  /* function to call */
819         .data = NULL,      /* 2nd arg of func */
820         .help_str = help_range_period,
821         .tokens = {        /* token list, NULL terminated */
822                 (PGM_P)&cmd_range_period_range_period,
823                 (PGM_P)&cmd_range_period_action,
824                 (PGM_P)&cmd_range_period_period,
825                 NULL,
826         },
827 };
828
829 /* ************* */
830
831 /* this structure is filled when cmd_range_count is parsed successfully */
832 struct cmd_range_count_result {
833         fixed_string_t range;
834         fixed_string_t action;
835         uint32_t count;
836 };
837
838 /* function called when cmd_range_count is parsed successfully */
839 static void cmd_range_count_parsed(void *parsed_result, void *data)
840 {
841         struct cmd_range_count_result *res = parsed_result;
842
843         (void)data;
844         range_count = res->count;
845 }
846
847 const char PROGMEM str_count[] = "count";
848
849 const parse_token_string_t PROGMEM cmd_range_count_range_count =
850         TOKEN_STRING_INITIALIZER(struct cmd_range_count_result, range,
851                                  str_range);
852 const parse_token_string_t PROGMEM cmd_range_count_action =
853         TOKEN_STRING_INITIALIZER(struct cmd_range_count_result, action,
854                                  str_count);
855 const parse_token_num_t PROGMEM cmd_range_count_count =
856         TOKEN_NUM_INITIALIZER(struct cmd_range_count_result, count, UINT32);
857
858
859 const char PROGMEM help_range_count[] = "set range test count";
860
861 const parse_inst_t PROGMEM cmd_range_count = {
862         .f = cmd_range_count_parsed,  /* function to call */
863         .data = NULL,      /* 2nd arg of func */
864         .help_str = help_range_count,
865         .tokens = {        /* token list, NULL terminated */
866                 (PGM_P)&cmd_range_count_range_count,
867                 (PGM_P)&cmd_range_count_action,
868                 (PGM_P)&cmd_range_count_count,
869                 NULL,
870         },
871 };
872
873 /* ************* */
874
875 /* this structure is filled when cmd_range_powermask is parsed successfully */
876 struct cmd_range_powermask_result {
877         fixed_string_t range;
878         fixed_string_t action;
879         uint8_t powermask;
880 };
881
882 /* function called when cmd_range_powermask is parsed successfully */
883 static void cmd_range_powermask_parsed(void *parsed_result, void *data)
884 {
885         struct cmd_range_powermask_result *res = parsed_result;
886
887         (void)data;
888         range_powermask = res->powermask;
889 }
890
891 const char PROGMEM str_powermask[] = "powermask";
892
893 const parse_token_string_t PROGMEM cmd_range_powermask_range_powermask =
894         TOKEN_STRING_INITIALIZER(struct cmd_range_powermask_result, range,
895                                  str_range);
896 const parse_token_string_t PROGMEM cmd_range_powermask_action =
897         TOKEN_STRING_INITIALIZER(struct cmd_range_powermask_result, action,
898                                  str_powermask);
899 const parse_token_num_t PROGMEM cmd_range_powermask_powermask =
900         TOKEN_NUM_INITIALIZER(struct cmd_range_powermask_result, powermask,
901                               UINT8);
902
903
904 const char PROGMEM help_range_powermask[] = "set range test powermask";
905
906 const parse_inst_t PROGMEM cmd_range_powermask = {
907         .f = cmd_range_powermask_parsed,  /* function to call */
908         .data = NULL,      /* 2nd arg of func */
909         .help_str = help_range_powermask,
910         .tokens = {        /* token list, NULL terminated */
911                 (PGM_P)&cmd_range_powermask_range_powermask,
912                 (PGM_P)&cmd_range_powermask_action,
913                 (PGM_P)&cmd_range_powermask_powermask,
914                 NULL,
915         },
916 };
917
918 /* ************* */
919
920 /* this structure is filled when cmd_range_dstaddr is parsed successfully */
921 struct cmd_range_dstaddr_result {
922         fixed_string_t range;
923         fixed_string_t action;
924         uint64_t dstaddr;
925 };
926
927 /* function called when cmd_range_dstaddr is parsed successfully */
928 static void cmd_range_dstaddr_parsed(void *parsed_result, void *data)
929 {
930         struct cmd_range_dstaddr_result *res = parsed_result;
931
932         (void)data;
933         range_dstaddr = res->dstaddr;
934 }
935
936 const char PROGMEM str_dstaddr[] = "dstaddr";
937
938 const parse_token_string_t PROGMEM cmd_range_dstaddr_range_dstaddr =
939         TOKEN_STRING_INITIALIZER(struct cmd_range_dstaddr_result, range,
940                                  str_range);
941 const parse_token_string_t PROGMEM cmd_range_dstaddr_action =
942         TOKEN_STRING_INITIALIZER(struct cmd_range_dstaddr_result, action,
943                                  str_dstaddr);
944 const parse_token_num_t PROGMEM cmd_range_dstaddr_dstaddr =
945         TOKEN_NUM_INITIALIZER(struct cmd_range_dstaddr_result, dstaddr, UINT64);
946
947
948 const char PROGMEM help_range_dstaddr[] = "set register rangeing dstaddr";
949
950 const parse_inst_t PROGMEM cmd_range_dstaddr = {
951         .f = cmd_range_dstaddr_parsed,  /* function to call */
952         .data = NULL,      /* 2nd arg of func */
953         .help_str = help_range_dstaddr,
954         .tokens = {        /* token list, NULL terminated */
955                 (PGM_P)&cmd_range_dstaddr_range_dstaddr,
956                 (PGM_P)&cmd_range_dstaddr_action,
957                 (PGM_P)&cmd_range_dstaddr_dstaddr,
958                 NULL,
959         },
960 };
961
962
963 /* ************* */
964
965 /* this structure is filled when cmd_monitor is parsed successfully */
966 struct cmd_monitor_result {
967         fixed_string_t monitor;
968         fixed_string_t action;
969 };
970
971 /* function called when cmd_monitor is parsed successfully */
972 static void cmd_monitor_parsed(void *parsed_result, void *data)
973 {
974         struct cmd_monitor_result *res = parsed_result;
975         struct monitor_reg *m;
976
977         (void)data;
978         if (!strcmp_P(res->action, PSTR("show"))) {
979                 printf_P(PSTR("monitor period is %d ms, %d regs in list\r\n"),
980                        monitor_period_ms, monitor_count);
981                 LIST_FOREACH(m, &xbee_monitor_list, next)
982                         printf_P(PSTR(" %S\r\n"), m->desc);
983         }
984         else if (!strcmp_P(res->action, PSTR("start"))) {
985                 if (monitor_running) {
986                         printf_P(PSTR("already running\r\n"));
987                         return;
988                 }
989                 if (monitor_count == 0) {
990                         printf_P(PSTR("no regs to be monitored\r\n"));
991                         return;
992                 }
993                 callout_init(&monitor_event, monitor_cb, NULL, 0);
994                 callout_schedule(&xbeeboard.mainloop_cm,
995                         &monitor_event, 0); /* immediate */
996                 monitor_running = 1;
997                 monitor_current = LIST_FIRST(&xbee_monitor_list);
998                 printf_P(PSTR("monitor cb: %S %s\r\n"),
999                          monitor_current->desc,
1000                          monitor_current->atcmd);
1001
1002         }
1003         else if (!strcmp_P(res->action, PSTR("end"))) {
1004                 if (monitor_running == 0) {
1005                         printf_P(PSTR("not running\r\n"));
1006                         return;
1007                 }
1008                 monitor_running = 0;
1009                 callout_stop(&xbeeboard.mainloop_cm, &monitor_event);
1010         }
1011 }
1012
1013 const char PROGMEM str_monitor[] = "monitor";
1014 const char PROGMEM str_monitor_tokens[] = "show#start#end";
1015
1016 const parse_token_string_t PROGMEM cmd_monitor_monitor =
1017         TOKEN_STRING_INITIALIZER(struct cmd_monitor_result, monitor,
1018                                  str_monitor);
1019 const parse_token_string_t PROGMEM cmd_monitor_action =
1020         TOKEN_STRING_INITIALIZER(struct cmd_monitor_result, action,
1021                                  str_monitor_tokens);
1022
1023 const char PROGMEM help_monitor[] = "start/stop/show current monitoring";
1024
1025 const parse_inst_t PROGMEM cmd_monitor = {
1026         .f = cmd_monitor_parsed,  /* function to call */
1027         .data = NULL,      /* 2nd arg of func */
1028         .help_str = help_monitor,
1029         .tokens = {        /* token list, NULL terminated */
1030                 (PGM_P)&cmd_monitor_monitor,
1031                 (PGM_P)&cmd_monitor_action,
1032                 NULL,
1033         },
1034 };
1035
1036 /* ************* */
1037
1038 /* this structure is filled when cmd_monitor_add is parsed successfully */
1039 struct cmd_monitor_add_result {
1040         fixed_string_t monitor;
1041         fixed_string_t action;
1042         struct xbee_atcmd *cmd;
1043 };
1044
1045 /* function called when cmd_monitor_add is parsed successfully */
1046 static void cmd_monitor_add_parsed(void *parsed_result, void *data)
1047 {
1048         struct cmd_monitor_add_result *res = parsed_result;
1049         struct monitor_reg *m;
1050         struct xbee_atcmd copy;
1051
1052         (void)data;
1053         memcpy_P(&copy, res->cmd, sizeof(copy));
1054         LIST_FOREACH(m, &xbee_monitor_list, next) {
1055                 if (!strcmp_P(m->atcmd, copy.name))
1056                         break;
1057         }
1058
1059         if (m != NULL) {
1060                 printf_P(PSTR("already exist\r\n"));
1061                 return;
1062         }
1063
1064         m = malloc(sizeof(*m));
1065         if (m == NULL) {
1066                 printf_P(PSTR("no mem\r\n"));
1067                 return;
1068         }
1069         m->desc = copy.desc;
1070         strcpy_P(m->atcmd, copy.name);
1071         LIST_INSERT_HEAD(&xbee_monitor_list, m, next);
1072         monitor_count ++;
1073 }
1074
1075 const char PROGMEM str_monitor_add[] = "add";
1076
1077 const parse_token_string_t PROGMEM cmd_monitor_add_monitor_add =
1078         TOKEN_STRING_INITIALIZER(struct cmd_monitor_add_result, monitor,
1079                                  str_monitor);
1080 const parse_token_string_t PROGMEM cmd_monitor_add_action =
1081         TOKEN_STRING_INITIALIZER(struct cmd_monitor_add_result, action,
1082                                  str_monitor_add);
1083 const parse_token_atcmd_t PROGMEM cmd_monitor_add_atcmd =
1084         TOKEN_ATCMD_INITIALIZER(struct cmd_monitor_add_result, cmd, &xbee_dev,
1085                                 XBEE_ATCMD_F_READ, XBEE_ATCMD_F_READ);
1086
1087
1088 const char PROGMEM help_monitor_add[] = "add a register in monitor list";
1089
1090 const parse_inst_t PROGMEM cmd_monitor_add = {
1091         .f = cmd_monitor_add_parsed,  /* function to call */
1092         .data = NULL,      /* 2nd arg of func */
1093         .help_str = help_monitor_add,
1094         .tokens = {        /* token list, NULL terminated */
1095                 (PGM_P)&cmd_monitor_add_monitor_add,
1096                 (PGM_P)&cmd_monitor_add_action,
1097                 (PGM_P)&cmd_monitor_add_atcmd,
1098                 NULL,
1099         },
1100 };
1101
1102 /* ************* */
1103
1104 /* this structure is filled when cmd_monitor_period is parsed successfully */
1105 struct cmd_monitor_period_result {
1106         fixed_string_t monitor;
1107         fixed_string_t action;
1108         uint32_t period;
1109 };
1110
1111 /* function called when cmd_monitor_period is parsed successfully */
1112 static void cmd_monitor_period_parsed(void *parsed_result, void *data)
1113 {
1114         struct cmd_monitor_period_result *res = parsed_result;
1115
1116         (void)data;
1117         if (res->period < 100) {
1118                 printf_P(PSTR("error, minimum period is 100 ms\r\n"));
1119                 return;
1120         }
1121
1122         monitor_period_ms = res->period;
1123 }
1124
1125 const char PROGMEM str_monitor_period[] = "period";
1126
1127 const parse_token_string_t PROGMEM cmd_monitor_period_monitor_period =
1128         TOKEN_STRING_INITIALIZER(struct cmd_monitor_period_result, monitor,
1129                                  str_monitor);
1130 const parse_token_string_t PROGMEM cmd_monitor_period_action =
1131         TOKEN_STRING_INITIALIZER(struct cmd_monitor_period_result, action,
1132                                  str_monitor_period);
1133 const parse_token_num_t PROGMEM cmd_monitor_period_period =
1134         TOKEN_NUM_INITIALIZER(struct cmd_monitor_period_result, period, UINT32);
1135
1136
1137 const char PROGMEM help_monitor_period[] = "set register monitoring period";
1138
1139 const parse_inst_t PROGMEM cmd_monitor_period = {
1140         .f = cmd_monitor_period_parsed,  /* function to call */
1141         .data = NULL,      /* 2nd arg of func */
1142         .help_str = help_monitor_period,
1143         .tokens = {        /* token list, NULL terminated */
1144                 (PGM_P)&cmd_monitor_period_monitor_period,
1145                 (PGM_P)&cmd_monitor_period_action,
1146                 (PGM_P)&cmd_monitor_period_period,
1147                 NULL,
1148         },
1149 };
1150
1151 /* ************* */
1152
1153 /* this structure is filled when cmd_monitor_del is parsed successfully */
1154 struct cmd_monitor_del_result {
1155         fixed_string_t monitor;
1156         fixed_string_t action;
1157         struct monitor_reg *m;
1158 };
1159
1160 /* function called when cmd_monitor_del is parsed successfully */
1161 static void cmd_monitor_del_parsed(void *parsed_result, void *data)
1162 {
1163         struct cmd_monitor_del_result *res = parsed_result;
1164
1165         (void)data;
1166         monitor_current = LIST_NEXT(res->m, next);
1167         LIST_REMOVE(res->m, next);
1168         free(res->m);
1169         monitor_count --;
1170         if (monitor_count == 0) {
1171                 printf_P(PSTR("Disable monitoring, no more event\r\n"));
1172                 callout_stop(&xbeeboard.mainloop_cm, &monitor_event);
1173                 monitor_running = 0;
1174                 return;
1175         }
1176 }
1177
1178 const char PROGMEM str_monitor_del[] = "del";
1179
1180 const parse_token_string_t PROGMEM cmd_monitor_del_monitor_del =
1181         TOKEN_STRING_INITIALIZER(struct cmd_monitor_del_result, monitor,
1182                                  str_monitor);
1183 const parse_token_string_t PROGMEM cmd_monitor_del_action =
1184         TOKEN_STRING_INITIALIZER(struct cmd_monitor_del_result, action,
1185                                  str_monitor_del);
1186 const parse_token_monitor_t PROGMEM cmd_monitor_del_atcmd =
1187         TOKEN_MONITOR_INITIALIZER(struct cmd_monitor_del_result, m);
1188
1189
1190 const char PROGMEM help_monitor_del[] = "del a register in monitor list";
1191
1192 const parse_inst_t PROGMEM cmd_monitor_del = {
1193         .f = cmd_monitor_del_parsed,  /* function to call */
1194         .data = NULL,      /* 2nd arg of func */
1195         .help_str = help_monitor_del,
1196         .tokens = {        /* token list, NULL terminated */
1197                 (PGM_P)&cmd_monitor_del_monitor_del,
1198                 (PGM_P)&cmd_monitor_del_action,
1199                 (PGM_P)&cmd_monitor_del_atcmd,
1200                 NULL,
1201         },
1202 };
1203
1204
1205 /* ************* */
1206
1207 /* this structure is filled when cmd_ping is parsed successfully */
1208 struct cmd_ping_result {
1209         fixed_string_t ping;
1210 };
1211
1212 /* function called when cmd_ping is parsed successfully */
1213 static void cmd_ping_parsed(void *parsed_result, void *data)
1214 {
1215         (void)parsed_result;
1216         (void)data;
1217         xbeeapp_send_atcmd("VL", NULL, 0, 1, NULL, NULL);
1218 }
1219
1220 const char PROGMEM str_ping[] = "ping";
1221
1222 const parse_token_string_t PROGMEM cmd_ping_ping =
1223         TOKEN_STRING_INITIALIZER(struct cmd_ping_result, ping,
1224                                  str_ping);
1225
1226 const char PROGMEM help_ping[] = "Send a ping to the xbee device";
1227
1228 const parse_inst_t PROGMEM cmd_ping = {
1229         .f = cmd_ping_parsed,  /* function to call */
1230         .data = NULL,      /* 2nd arg of func */
1231         .help_str = help_ping,
1232         .tokens = {        /* token list, NULL terminated */
1233                 (PGM_P)&cmd_ping_ping,
1234                 NULL,
1235         },
1236 };
1237
1238 /* ************* */
1239
1240 /* this structure is filled when cmd_raw is parsed successfully */
1241 struct cmd_raw_result {
1242         fixed_string_t raw;
1243 };
1244
1245 /* function called when cmd_raw is parsed successfully */
1246 static void cmd_raw_parsed(void *parsed_result, void *data)
1247 {
1248         (void)parsed_result;
1249         (void)data;
1250         printf_P(PSTR("switched to raw mode, CTRL-D to exit\r\n"));
1251         rdline_stop(&xbeeboard.rdl); /* don't display prompt when return */
1252         xbee_raw = 1;
1253 }
1254
1255 const char PROGMEM str_raw[] = "raw";
1256
1257 const parse_token_string_t PROGMEM cmd_raw_raw =
1258         TOKEN_STRING_INITIALIZER(struct cmd_raw_result, raw,
1259                                  str_raw);
1260
1261 const char PROGMEM help_raw[] = "Switch to raw mode";
1262
1263 const parse_inst_t PROGMEM cmd_raw = {
1264         .f = cmd_raw_parsed,  /* function to call */
1265         .data = NULL,      /* 2nd arg of func */
1266         .help_str = help_raw,
1267         .tokens = {        /* token list, NULL terminated */
1268                 (PGM_P)&cmd_raw_raw,
1269                 NULL,
1270         },
1271 };
1272
1273 /* ************* */
1274
1275 /* this structure is filled when cmd_dump is parsed successfully */
1276 struct cmd_dump_result {
1277         fixed_string_t dump;
1278         fixed_string_t onoff;
1279 };
1280
1281 /* function called when cmd_dump is parsed successfully */
1282 static void cmd_dump_parsed(void *parsed_result, void *data)
1283 {
1284         struct cmd_dump_result *res = parsed_result;
1285
1286         (void)data;
1287         if (!strcmp(res->onoff, "on"))
1288                 xbee_hexdump = 1;
1289         else
1290                 xbee_hexdump = 0;
1291 }
1292
1293 const char PROGMEM str_dump[] = "dump";
1294 const char PROGMEM str_dump_onoff[] = "on#off";
1295
1296 const parse_token_string_t PROGMEM cmd_dump_dump =
1297         TOKEN_STRING_INITIALIZER(struct cmd_dump_result, dump,
1298                                  str_dump);
1299
1300 const parse_token_string_t PROGMEM cmd_dump_onoff =
1301         TOKEN_STRING_INITIALIZER(struct cmd_dump_result, onoff,
1302                                  str_dump_onoff);
1303
1304 const char PROGMEM help_dump[] = "enable/disable hexdump of received packets";
1305
1306 const parse_inst_t PROGMEM cmd_dump = {
1307         .f = cmd_dump_parsed,  /* function to call */
1308         .data = NULL,      /* 2nd arg of func */
1309         .help_str = help_dump,
1310         .tokens = {        /* token list, NULL terminated */
1311                 (PGM_P)&cmd_dump_dump,
1312                 (PGM_P)&cmd_dump_onoff,
1313                 NULL,
1314         },
1315 };
1316
1317 /* ************* */
1318
1319 /* this structure is filled when cmd_debug is parsed successfully */
1320 struct cmd_debug_result {
1321         fixed_string_t debug;
1322         fixed_string_t onoff;
1323 };
1324
1325 /* function called when cmd_debug is parsed successfully */
1326 static void cmd_debug_parsed(void *parsed_result, void *data)
1327 {
1328         struct cmd_debug_result *res = parsed_result;
1329
1330         (void)data;
1331         if (!strcmp(res->onoff, "on"))
1332                 xbee_debug = 1;
1333         else
1334                 xbee_debug = 0;
1335 }
1336
1337 const char PROGMEM str_debug[] = "debug";
1338 const char PROGMEM str_debug_onoff[] = "on#off";
1339
1340 const parse_token_string_t PROGMEM cmd_debug_debug =
1341         TOKEN_STRING_INITIALIZER(struct cmd_debug_result, debug,
1342                                  str_debug);
1343
1344 const parse_token_string_t PROGMEM cmd_debug_onoff =
1345         TOKEN_STRING_INITIALIZER(struct cmd_debug_result, onoff,
1346                                  str_debug_onoff);
1347
1348 const char PROGMEM help_debug[] = "enable/disable additionnal debug";
1349
1350 const parse_inst_t PROGMEM cmd_debug = {
1351         .f = cmd_debug_parsed,  /* function to call */
1352         .data = NULL,      /* 2nd arg of func */
1353         .help_str = help_debug,
1354         .tokens = {        /* token list, NULL terminated */
1355                 (PGM_P)&cmd_debug_debug,
1356                 (PGM_P)&cmd_debug_onoff,
1357                 NULL,
1358         },
1359 };
1360
1361 /**********************************************************/
1362
1363 /* this structure is filled when cmd_baudrate is parsed successfully */
1364 struct cmd_baudrate_result {
1365         fixed_string_t arg0;
1366         uint32_t arg1;
1367 };
1368
1369 /* function called when cmd_baudrate is parsed successfully */
1370 static void cmd_baudrate_parsed(void * parsed_result, __attribute__((unused)) void *data)
1371 {
1372         struct cmd_baudrate_result *res = parsed_result;
1373         struct uart_config c;
1374
1375         uart_getconf(XBEE_UART, &c);
1376         c.baudrate = res->arg1;
1377         uart_setconf(XBEE_UART, &c);
1378 }
1379
1380 const char PROGMEM str_baudrate_arg0[] = "baudrate";
1381 const parse_token_string_t PROGMEM cmd_baudrate_arg0 =
1382         TOKEN_STRING_INITIALIZER(struct cmd_baudrate_result, arg0,
1383                                  str_baudrate_arg0);
1384 const parse_token_num_t PROGMEM cmd_baudrate_arg1 =
1385         TOKEN_NUM_INITIALIZER(struct cmd_baudrate_result, arg1,
1386                               UINT32);
1387
1388 const char PROGMEM help_baudrate[] = "Change xbee baudrate";
1389 const parse_inst_t PROGMEM cmd_baudrate = {
1390         .f = cmd_baudrate_parsed,  /* function to call */
1391         .data = NULL,      /* 2nd arg of func */
1392         .help_str = help_baudrate,
1393         .tokens = {        /* token list, NULL terminated */
1394                 (PGM_P)&cmd_baudrate_arg0,
1395                 (PGM_P)&cmd_baudrate_arg1,
1396                 NULL,
1397         },
1398 };
1399
1400
1401 /**********************************************************/
1402
1403 /* this structure is filled when cmd_beep is parsed successfully */
1404 struct cmd_beep_result {
1405         fixed_string_t beep;
1406 };
1407
1408 /* function called when cmd_beep is parsed successfully */
1409 static void cmd_beep_parsed(void *parsed_result, void *data)
1410 {
1411         (void)parsed_result;
1412         (void)data;
1413
1414         beep(0, 3, 3);
1415         beep(1, 3, 3);
1416         beep(2, 3, 3);
1417         beep(0, 1, 1);
1418         beep(1, 1, 1);
1419         beep(2, 1, 1);
1420 }
1421
1422 const char PROGMEM str_beep[] = "beep";
1423 const parse_token_string_t PROGMEM cmd_beep_beep =
1424         TOKEN_STRING_INITIALIZER(struct cmd_beep_result, beep,
1425                                  str_beep);
1426
1427 const char PROGMEM help_beep[] = "Send a beep";
1428
1429 const parse_inst_t PROGMEM cmd_beep = {
1430         .f = cmd_beep_parsed,  /* function to call */
1431         .data = NULL,      /* 2nd arg of func */
1432         .help_str = help_beep,
1433         .tokens = {        /* token list, NULL terminated */
1434                 (PGM_P)&cmd_beep_beep,
1435                 NULL,
1436         },
1437 };
1438
1439 /**********************************************************/
1440
1441 /* this structure is filled when cmd_servo is parsed successfully */
1442 struct cmd_servo_result {
1443         fixed_string_t arg0;
1444         fixed_string_t arg1;
1445         uint16_t num;
1446         uint16_t val;
1447 };
1448
1449 /* function called when cmd_servo is parsed successfully */
1450 static void cmd_servo_parsed(void * parsed_result, void *data)
1451 {
1452         struct cmd_servo_result *res = parsed_result;
1453
1454         (void)data;
1455
1456         if (!strcmp_P(res->arg1, PSTR("set"))) {
1457                 if (res->num >= N_SERVO) {
1458                         printf_P(PSTR("bad servo num\n"));
1459                         return;
1460                 }
1461                 if (res->val >= 1024) {
1462                         printf_P(PSTR("bad servo val\n"));
1463                         return;
1464                 }
1465                 spi_servo_set(res->num, res->val);
1466         }
1467         else if (!strcmp_P(res->arg1, PSTR("bypass"))) {
1468                 spi_servo_set_bypass(!!res->val);
1469         }
1470         else if (!strcmp_P(res->arg1, PSTR("ppm"))) {
1471                 spi_servo_set_ppm(!!res->val);
1472         }
1473         else if (!strcmp_P(res->arg1, PSTR("show"))) {
1474                 spi_servo_dump();
1475         }
1476 }
1477
1478 const char PROGMEM str_servo_arg0[] = "servo";
1479 const parse_token_string_t PROGMEM cmd_servo_arg0 =
1480         TOKEN_STRING_INITIALIZER(struct cmd_servo_result, arg0,
1481                                  str_servo_arg0);
1482 const char PROGMEM str_servo_arg1_set[] = "set";
1483 const parse_token_string_t PROGMEM cmd_servo_arg1_set =
1484         TOKEN_STRING_INITIALIZER(struct cmd_servo_result, arg1,
1485                                  str_servo_arg1_set);
1486 const parse_token_num_t PROGMEM cmd_servo_num =
1487         TOKEN_NUM_INITIALIZER(struct cmd_servo_result, num,
1488                               UINT16);
1489 const parse_token_num_t PROGMEM cmd_servo_val =
1490         TOKEN_NUM_INITIALIZER(struct cmd_servo_result, val,
1491                               UINT16);
1492
1493 const char PROGMEM help_servo_set[] = "set servo value";
1494 const parse_inst_t PROGMEM cmd_servo_set = {
1495         .f = cmd_servo_parsed,  /* function to call */
1496         .data = NULL,      /* 2nd arg of func */
1497         .help_str = help_servo_set,
1498         .tokens = {        /* token list, NULL terminated */
1499                 (PGM_P)&cmd_servo_arg0,
1500                 (PGM_P)&cmd_servo_arg1_set,
1501                 (PGM_P)&cmd_servo_num,
1502                 (PGM_P)&cmd_servo_val,
1503                 NULL,
1504         },
1505 };
1506
1507 const char PROGMEM str_servo_arg1_show[] = "show";
1508 const parse_token_string_t PROGMEM cmd_servo_arg1_show =
1509         TOKEN_STRING_INITIALIZER(struct cmd_servo_result, arg1,
1510                                  str_servo_arg1_show);
1511
1512 const char PROGMEM help_servo_show[] = "read servo and config";
1513 const parse_inst_t PROGMEM cmd_servo_show = {
1514         .f = cmd_servo_parsed,  /* function to call */
1515         .data = NULL,      /* 2nd arg of func */
1516         .help_str = help_servo_show,
1517         .tokens = {        /* token list, NULL terminated */
1518                 (PGM_P)&cmd_servo_arg0,
1519                 (PGM_P)&cmd_servo_arg1_show,
1520                 NULL,
1521         },
1522 };
1523
1524 const char PROGMEM str_servo_arg1_bypassppm[] = "bypass#ppm";
1525 const parse_token_string_t PROGMEM cmd_servo_arg1_bypassppm =
1526         TOKEN_STRING_INITIALIZER(struct cmd_servo_result, arg1,
1527                                  str_servo_arg1_bypassppm);
1528
1529 const char PROGMEM help_servo_bypassppm[] = "change bypass/ppm";
1530 const parse_inst_t PROGMEM cmd_servo_bypassppm = {
1531         .f = cmd_servo_parsed,  /* function to call */
1532         .data = NULL,      /* 2nd arg of func */
1533         .help_str = help_servo_bypassppm,
1534         .tokens = {        /* token list, NULL terminated */
1535                 (PGM_P)&cmd_servo_arg0,
1536                 (PGM_P)&cmd_servo_arg1_bypassppm,
1537                 (PGM_P)&cmd_servo_val,
1538                 NULL,
1539         },
1540 };
1541
1542 /**********************************************************/
1543
1544 /* this structure is filled when cmd_test_spi is parsed successfully */
1545 struct cmd_test_spi_result {
1546         fixed_string_t arg0;
1547 };
1548
1549 static void cmd_test_spi_parsed(void * parsed_result, void *data)
1550 {
1551         uint8_t i, flags, wait_time = 0;
1552         uint16_t val = 0;
1553
1554         (void)parsed_result;
1555         (void)data;
1556
1557         spi_servo_set_bypass(0);
1558         spi_servo_set_ppm(0);
1559
1560         /* stress test: send many commands, no wait between each servo
1561          * of a series, and a variable delay between series */
1562         printf_P(PSTR("stress test\r\n"));
1563         while (!cmdline_keypressed()) {
1564
1565                 wait_time++;
1566                 if (wait_time > 20)
1567                         wait_time = 0;
1568
1569                 IRQ_LOCK(flags);
1570                 val = global_ms;
1571                 IRQ_UNLOCK(flags);
1572                 val >>= 3;
1573                 val &= 1023;
1574
1575                 for (i = 0; i < 6; i++)
1576                         spi_servo_set(i, val);
1577
1578                 wait_ms(wait_time);
1579                 printf_P(PSTR("%4.4d %4.4d %4.4d %4.4d %4.4d %4.4d\r\n"),
1580                          spi_servo_get(0), spi_servo_get(1), spi_servo_get(2),
1581                          spi_servo_get(3), spi_servo_get(4), spi_servo_get(5));
1582         }
1583
1584         printf_P(PSTR("bypass mode, with spi commands in background\r\n"));
1585         spi_servo_set_bypass(1);
1586
1587         /* test bypass mode */
1588         while (!cmdline_keypressed()) {
1589
1590                 wait_time++;
1591                 if (wait_time > 20)
1592                         wait_time = 0;
1593
1594                 IRQ_LOCK(flags);
1595                 val = global_ms;
1596                 IRQ_UNLOCK(flags);
1597                 val >>= 3;
1598                 val &= 1023;
1599
1600                 for (i = 0; i < 6; i++)
1601                         spi_servo_set(i, val);
1602
1603                 wait_ms(wait_time);
1604                 printf_P(PSTR("%4.4d %4.4d %4.4d %4.4d %4.4d %4.4d\r\n"),
1605                          spi_servo_get(0), spi_servo_get(1), spi_servo_get(2),
1606                          spi_servo_get(3), spi_servo_get(4), spi_servo_get(5));
1607         }
1608
1609         printf_P(PSTR("PPM to servo\r\n"));
1610         spi_servo_set_bypass(0);
1611         spi_servo_set_ppm(0);
1612
1613         /* test PPM to servo (bypass) mode */
1614         while (!cmdline_keypressed()) {
1615                 for (i = 0; i < 6; i++) {
1616                         val = spi_servo_get(i);
1617                         spi_servo_set(i, val);
1618                 }
1619         }
1620
1621         printf_P(PSTR("PPM to (servo + PPM)\r\n"));
1622         spi_servo_set_bypass(0);
1623         spi_servo_set_ppm(1);
1624
1625         /* test PPM to servo (bypass) mode */
1626         while (!cmdline_keypressed()) {
1627                 for (i = 0; i < 6; i++) {
1628                         val = spi_servo_get(i);
1629                         spi_servo_set(i, val);
1630                 }
1631         }
1632 }
1633
1634 const char PROGMEM str_test_spi_arg0[] = "test_spi";
1635 const parse_token_string_t PROGMEM cmd_test_spi_arg0 =
1636         TOKEN_STRING_INITIALIZER(struct cmd_test_spi_result, arg0,
1637                                  str_test_spi_arg0);
1638
1639 const char PROGMEM help_test_spi[] = "Test the spi";
1640 const parse_inst_t PROGMEM cmd_test_spi = {
1641         .f = cmd_test_spi_parsed,  /* function to call */
1642         .data = NULL,      /* 2nd arg of func */
1643         .help_str = help_test_spi,
1644         .tokens = {        /* token list, NULL terminated */
1645                 (PGM_P)&cmd_test_spi_arg0,
1646                 NULL,
1647         },
1648 };
1649
1650 /**********************************************************/
1651
1652 /* this structure is filled when cmd_dump_xbee_stats is parsed successfully */
1653 struct cmd_dump_xbee_stats_result {
1654         fixed_string_t arg0;
1655 };
1656
1657 static void cmd_dump_xbee_stats_parsed(void *parsed_result, void *data)
1658 {
1659         (void)parsed_result;
1660         (void)data;
1661
1662         xbee_dump_stats(xbee_dev);
1663 }
1664
1665 const char PROGMEM str_dump_xbee_stats_arg0[] = "dump_xbee_stats";
1666 const parse_token_string_t PROGMEM cmd_dump_xbee_stats_arg0 =
1667         TOKEN_STRING_INITIALIZER(struct cmd_dump_xbee_stats_result, arg0,
1668                                  str_dump_xbee_stats_arg0);
1669
1670 const char PROGMEM help_dump_xbee_stats[] = "Test the spi";
1671 const parse_inst_t PROGMEM cmd_dump_xbee_stats = {
1672         .f = cmd_dump_xbee_stats_parsed,  /* function to call */
1673         .data = NULL,      /* 2nd arg of func */
1674         .help_str = help_dump_xbee_stats,
1675         .tokens = {        /* token list, NULL terminated */
1676                 (PGM_P)&cmd_dump_xbee_stats_arg0,
1677                 NULL,
1678         },
1679 };
1680
1681 /**********************************************************/
1682
1683 /* this structure is filled when cmd_test_eeprom_config is parsed successfully */
1684 struct cmd_test_eeprom_config_result {
1685         fixed_string_t arg0;
1686 };
1687
1688 static void cmd_test_eeprom_config_parsed(void *parsed_result, void *data)
1689 {
1690         (void)parsed_result;
1691         (void)data;
1692
1693         eeprom_dump_cmds();
1694         eeprom_append_cmd("salut1\n");
1695         eeprom_dump_cmds();
1696         eeprom_append_cmd("salut2\n");
1697         eeprom_append_cmd("salut3\n");
1698         eeprom_append_cmd("salut4\n");
1699         eeprom_dump_cmds();
1700         eeprom_insert_cmd_before("coin\n", 0);
1701         eeprom_insert_cmd_before("coin2\n", 2);
1702         eeprom_dump_cmds();
1703         eeprom_delete_cmd(2);
1704         eeprom_delete_cmd(0);
1705         eeprom_dump_cmds();
1706 }
1707
1708 const char PROGMEM str_test_eeprom_config_arg0[] = "test_eeprom_config";
1709 const parse_token_string_t PROGMEM cmd_test_eeprom_config_arg0 =
1710         TOKEN_STRING_INITIALIZER(struct cmd_test_eeprom_config_result, arg0,
1711                                  str_test_eeprom_config_arg0);
1712
1713 const char PROGMEM help_test_eeprom_config[] = "Test the eeprom configuration";
1714 const parse_inst_t PROGMEM cmd_test_eeprom_config = {
1715         .f = cmd_test_eeprom_config_parsed,  /* function to call */
1716         .data = NULL,      /* 2nd arg of func */
1717         .help_str = help_test_eeprom_config,
1718         .tokens = {        /* token list, NULL terminated */
1719                 (PGM_P)&cmd_test_eeprom_config_arg0,
1720                 NULL,
1721         },
1722 };
1723
1724 /* ************* */
1725
1726 struct cmd_eeprom_del_result {
1727         fixed_string_t cmd;
1728         fixed_string_t action;
1729         uint8_t n;
1730 };
1731
1732 static void cmd_eeprom_del_parsed(void *parsed_result,
1733                                 void *data)
1734 {
1735         struct cmd_eeprom_del_result *res = parsed_result;
1736
1737         (void)data;
1738         if (eeprom_delete_cmd(res->n) < 0)
1739                 printf_P(PSTR("cannot delete command\n"));
1740         eeprom_dump_cmds();
1741 }
1742
1743 const char PROGMEM str_eeprom_del_eeprom[] = "eeprom";
1744 const parse_token_string_t PROGMEM cmd_eeprom_del_cmd =
1745         TOKEN_STRING_INITIALIZER(struct cmd_eeprom_del_result, cmd,
1746                                  str_eeprom_del_eeprom);
1747 const char PROGMEM str_eeprom_del_del[] = "del";
1748 const parse_token_string_t PROGMEM cmd_eeprom_del_action =
1749         TOKEN_STRING_INITIALIZER(struct cmd_eeprom_del_result, action,
1750                                  str_eeprom_del_del);
1751 const parse_token_num_t PROGMEM cmd_eeprom_del_num =
1752         TOKEN_NUM_INITIALIZER(struct cmd_eeprom_del_result, n,
1753                               UINT8);
1754
1755 const char PROGMEM help_eeprom_del[] = "delete an eeprom init command";
1756 const parse_inst_t PROGMEM cmd_eeprom_del = {
1757         .f = cmd_eeprom_del_parsed,  /* function to call */
1758         .data = NULL,      /* 2nd arg of func */
1759         .help_str = help_eeprom_del,
1760         .tokens = {        /* token list, NULL terminated */
1761                 (PGM_P)&cmd_eeprom_del_cmd,
1762                 (PGM_P)&cmd_eeprom_del_action,
1763                 (PGM_P)&cmd_eeprom_del_num,
1764                 NULL,
1765         },
1766 };
1767
1768 /* ************* */
1769
1770 struct cmd_eeprom_add_result {
1771         fixed_string_t cmd;
1772         fixed_string_t action;
1773         uint8_t n;
1774 };
1775
1776 static void cmd_eeprom_add_parsed(void *parsed_result,
1777                                  void *data)
1778 {
1779         struct cmd_eeprom_add_result *res = parsed_result;
1780         struct rdline rdl;
1781         const char *buffer;
1782         int8_t ret;
1783         int16_t c;
1784
1785         rdline_init(&rdl, cmdline_write_char, NULL, NULL);
1786         rdline_newline(&rdl, "> ");
1787
1788         /* XXX bad: we should not block as we do not serve callout */
1789         while (1) {
1790                 c = cmdline_dev_recv(NULL);
1791                 if (c < 0)
1792                         continue;
1793
1794                 ret = rdline_char_in(&rdl, c);
1795                 if (ret == -2) {
1796                         printf_P(PSTR("abort\n"));
1797                         return;
1798                 }
1799                 if (ret == 1)
1800                         break;
1801         }
1802
1803         buffer = rdline_get_buffer(&rdl);
1804         if (data == NULL)
1805                 eeprom_insert_cmd_before(buffer, res->n);
1806         else
1807                 eeprom_append_cmd(buffer);
1808         eeprom_dump_cmds();
1809 }
1810
1811 const char PROGMEM str_eeprom_add_eeprom[] = "eeprom";
1812 const parse_token_string_t PROGMEM cmd_eeprom_add_cmd =
1813         TOKEN_STRING_INITIALIZER(struct cmd_eeprom_add_result, cmd,
1814                                  str_eeprom_add_eeprom);
1815 const char PROGMEM str_eeprom_add_add[] = "add";
1816 const parse_token_string_t PROGMEM cmd_eeprom_add_action =
1817         TOKEN_STRING_INITIALIZER(struct cmd_eeprom_add_result, action,
1818                                  str_eeprom_add_add);
1819 const parse_token_num_t PROGMEM cmd_eeprom_add_num =
1820         TOKEN_NUM_INITIALIZER(struct cmd_eeprom_add_result, n,
1821                               UINT8);
1822
1823 const char PROGMEM help_eeprom_add[] = "insert an eeprom init command";
1824 const parse_inst_t PROGMEM cmd_eeprom_add = {
1825         .f = cmd_eeprom_add_parsed,  /* function to call */
1826         .data = NULL,      /* 2nd arg of func */
1827         .help_str = help_eeprom_add,
1828         .tokens = {        /* token list, NULL terminated */
1829                 (PGM_P)&cmd_eeprom_add_cmd,
1830                 (PGM_P)&cmd_eeprom_add_action,
1831                 (PGM_P)&cmd_eeprom_add_num,
1832                 NULL,
1833         },
1834 };
1835
1836 const char PROGMEM help_eeprom_add2[] = "append an eeprom init command";
1837 const parse_inst_t PROGMEM cmd_eeprom_add2 = {
1838         .f = cmd_eeprom_add_parsed,  /* function to call */
1839         .data = (void *)1,      /* 2nd arg of func */
1840         .help_str = help_eeprom_add2,
1841         .tokens = {        /* token list, NULL terminated */
1842                 (PGM_P)&cmd_eeprom_add_cmd,
1843                 (PGM_P)&cmd_eeprom_add_action,
1844                 NULL,
1845         },
1846 };
1847
1848 /* ************* */
1849
1850 struct cmd_eeprom_list_result {
1851         fixed_string_t cmd;
1852         fixed_string_t action;
1853 };
1854
1855 static void cmd_eeprom_list_parsed(void *parsed_result,
1856                                 void *data)
1857 {
1858         (void)parsed_result;
1859         (void)data;
1860         eeprom_dump_cmds();
1861 }
1862
1863 const char PROGMEM str_eeprom_list_eeprom[] = "eeprom";
1864 const parse_token_string_t PROGMEM cmd_eeprom_list_cmd =
1865         TOKEN_STRING_INITIALIZER(struct cmd_eeprom_list_result, cmd,
1866                                  str_eeprom_list_eeprom);
1867 const char PROGMEM str_eeprom_list_list[] = "list";
1868 const parse_token_string_t PROGMEM cmd_eeprom_list_action =
1869         TOKEN_STRING_INITIALIZER(struct cmd_eeprom_list_result, action,
1870                                  str_eeprom_list_list);
1871
1872 const char PROGMEM help_eeprom_list[] = "list all eeprom init commands";
1873 const parse_inst_t PROGMEM cmd_eeprom_list = {
1874         .f = cmd_eeprom_list_parsed,  /* function to call */
1875         .data = NULL,      /* 2nd arg of func */
1876         .help_str = help_eeprom_list,
1877         .tokens = {        /* token list, NULL terminated */
1878                 (PGM_P)&cmd_eeprom_list_cmd,
1879                 (PGM_P)&cmd_eeprom_list_action,
1880                 NULL,
1881         },
1882 };
1883
1884
1885 /* ************* */
1886
1887 /* in progmem */
1888 const parse_ctx_t PROGMEM main_ctx[] = {
1889
1890         /* commands_gen.c */
1891         &cmd_reset,
1892         &cmd_bootloader,
1893         &cmd_log,
1894         &cmd_log_show,
1895         &cmd_log_type,
1896         &cmd_stack_space,
1897         &cmd_callout,
1898         &cmd_help,
1899         &cmd_neigh_del,
1900         &cmd_neigh_add,
1901         &cmd_neigh_list,
1902         &cmd_read,
1903         &cmd_write_none,
1904         &cmd_write_u8,
1905         &cmd_write_u16,
1906         &cmd_write_u32,
1907         &cmd_sendmsg,
1908         &cmd_send_hello,
1909         &cmd_send_hello_name,
1910         &cmd_sendmsg_name,
1911         &cmd_range,
1912         &cmd_range_period,
1913         &cmd_range_count,
1914         &cmd_range_powermask,
1915         &cmd_range_dstaddr,
1916         &cmd_monitor,
1917         &cmd_monitor_period,
1918         &cmd_monitor_add,
1919         &cmd_monitor_del,
1920         &cmd_ping,
1921         &cmd_raw,
1922         &cmd_dump,
1923         &cmd_debug,
1924         &cmd_baudrate,
1925         &cmd_beep,
1926         &cmd_servo_set,
1927         &cmd_servo_bypassppm,
1928         &cmd_servo_show,
1929         &cmd_test_spi,
1930         &cmd_dump_xbee_stats,
1931         &cmd_test_eeprom_config,
1932         &cmd_eeprom_del,
1933         &cmd_eeprom_add,
1934         &cmd_eeprom_add2,
1935         &cmd_eeprom_list,
1936         NULL,
1937 };