fix home directory
[protos/xbee.git] / commands.c
1 /*
2  * Copyright (c) 2009, Olivier MATZ <zer0@droids-corp.org>
3  * All rights reserved.
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  *     * Redistributions of source code must retain the above copyright
8  *       notice, this list of conditions and the following disclaimer.
9  *     * Redistributions in binary form must reproduce the above copyright
10  *       notice, this list of conditions and the following disclaimer in the
11  *       documentation and/or other materials provided with the distribution.
12  *     * Neither the name of the University of California, Berkeley nor the
13  *       names of its contributors may be used to endorse or promote products
14  *       derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
17  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19  * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
20  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27
28 #include <stdio.h>
29 #include <stdint.h>
30 #include <string.h>
31 #include <stdlib.h>
32 #include <stdarg.h>
33 #include <errno.h>
34 #include <ctype.h>
35 #include <sys/queue.h>
36 #include <arpa/inet.h>
37 #include <inttypes.h>
38 #include <linux/joystick.h>
39
40 #include <event.h>
41
42 #include <cmdline_parse.h>
43 #include <cmdline_parse_num.h>
44 #include <cmdline_parse_string.h>
45 #include <cmdline_parse_file.h>
46 #include <cmdline.h>
47
48 #include "xbee_neighbor.h"
49 #include "xbee_atcmd.h"
50 #include "xbee_stats.h"
51 #include "xbee_buf.h"
52 #include "xbee_proto.h"
53 #include "xbee.h"
54 #include "parse_atcmd.h"
55 #include "parse_neighbor.h"
56 #include "parse_monitor.h"
57 #include "rc_proto.h"
58 #include "joystick.h"
59 #include "main.h"
60
61 static struct monitor_reg_list monitor_list = LIST_HEAD_INITIALIZER(x/*XXX*/);
62 static int monitor_period_ms = 1000;
63 static int monitor_running = 0;
64 static int monitor_count = 0;
65 static struct event monitor_event;
66 struct monitor_reg *monitor_current;
67
68 static int range_period_ms = 1000;
69 static int range_powermask = 0x1F;
70 static uint8_t range_power = 0;
71 static int range_running = 0;
72 static uint64_t range_dstaddr = 0xFFFF; /* broadcast by default */
73 static struct event range_event;
74 static int range_count = 100;
75 static int range_cur_count = 0;
76
77 static struct event rc_send_event;
78 static int rc_send_period_ms = 100;
79 static int rc_send_running = 0;
80 static const char *xbee_logfilename = "/tmp/xbee.log";
81
82 static void monitor_cb(int s, short event, void *arg)
83 {
84         struct timeval tv;
85         struct cmdline *cl = arg;
86
87         if (monitor_current == NULL)
88                 monitor_current = LIST_FIRST(&monitor_list);
89
90         xbeeapp_send_atcmd(monitor_current->atcmd, NULL, 0, 0, NULL, NULL);
91         monitor_current = LIST_NEXT(monitor_current, next);
92
93         evtimer_set(&monitor_event, monitor_cb, cl);
94         tv.tv_sec = 0;
95         tv.tv_usec = (1000 * monitor_period_ms) / monitor_count;
96         evtimer_add(&monitor_event, &tv);
97 }
98
99 static void range_cb(int s, short event, void *arg)
100 {
101         struct timeval tv;
102         struct cmdline *cl = arg;
103         char buf[16];
104         uint8_t i, mask;
105
106         range_cur_count--;
107
108         /* get new xmit power */
109         for (i = 1; i <= 8; i++) {
110                 mask = 1 << ((range_power + i) & 0x7);
111                 if (mask & range_powermask)
112                         break;
113         }
114         range_power = ((range_power + i) & 0x7);
115
116         xbeeapp_send_atcmd("PL", &range_power, sizeof(range_power), 0, NULL, NULL);
117         snprintf(buf, sizeof(buf), "range%d", range_power);
118         xbeeapp_send_msg(range_dstaddr, buf, strlen(buf), 0);
119
120         if (range_cur_count == 0) {
121                 range_running = 0;
122                 return;
123         }
124
125         evtimer_set(&range_event, range_cb, cl);
126         tv.tv_sec = 0;
127         tv.tv_usec = 1000 * range_period_ms;
128         evtimer_add(&range_event, &tv);
129 }
130
131
132 static void rc_send_cb(int fd, short event, void *arg)
133 {
134         struct cmdline *cl = arg;
135         struct timeval tv;
136
137         rc_proto_send_channels();
138
139         evtimer_set(&rc_send_event, rc_send_cb, cl);
140         tv.tv_sec = 0;
141         tv.tv_usec = 1000 * rc_send_period_ms;
142         evtimer_add(&rc_send_event, &tv);
143 }
144
145
146 /* ************* */
147
148 /* this structure is filled when cmd_stats is parsed successfully */
149 struct cmd_stats_result {
150         cmdline_fixed_string_t stats;
151         cmdline_fixed_string_t action;
152 };
153
154 /* function called when cmd_stats is parsed successfully */
155 static void cmd_stats_parsed(void *parsed_result, struct cmdline *cl, void *data)
156 {
157         struct cmd_stats_result *res = parsed_result;
158
159         if (!strcmp(res->action, "show")) {
160                 xbee_dump_stats(stdout, xbee_dev);
161                 if (xbee_logfile != NULL)
162                         xbee_dump_stats(xbee_logfile, xbee_dev);
163         }
164         else if (!strcmp(res->action, "reset"))
165                 xbee_reset_stats(xbee_dev);
166 }
167
168 cmdline_parse_token_string_t cmd_stats_stats =
169         TOKEN_STRING_INITIALIZER(struct cmd_stats_result, stats, "stats");
170 cmdline_parse_token_string_t cmd_stats_action =
171         TOKEN_STRING_INITIALIZER(struct cmd_stats_result, action, "show#reset");
172
173 cmdline_parse_inst_t cmd_stats = {
174         .f = cmd_stats_parsed,  /* function to call */
175         .data = NULL,      /* 2nd arg of func */
176         .help_str = "Send a stats to the xbee device",
177         .tokens = {        /* token list, NULL terminated */
178                 (void *)&cmd_stats_stats,
179                 (void *)&cmd_stats_action,
180                 NULL,
181         },
182 };
183
184 /* ************* */
185
186 /* this structure is filled when cmd_monitor is parsed successfully */
187 struct cmd_monitor_result {
188         cmdline_fixed_string_t monitor;
189         cmdline_fixed_string_t action;
190 };
191
192 /* function called when cmd_monitor is parsed successfully */
193 static void cmd_monitor_parsed(void *parsed_result, struct cmdline *cl,
194                                void *data)
195 {
196         struct cmd_monitor_result *res = parsed_result;
197         struct monitor_reg *m;
198
199         if (!strcmp(res->action, "show")) {
200                 printf("monitor period is %d ms, %d regs in list\n",
201                        monitor_period_ms, monitor_count);
202                 LIST_FOREACH(m, &monitor_list, next)
203                         printf(" %s\n", m->desc);
204         }
205         else if (!strcmp(res->action, "start")) {
206                 struct timeval tv;
207                 if (monitor_running) {
208                         printf("already running\n");
209                         return;
210                 }
211                 if (monitor_count == 0) {
212                         printf("no regs to be monitored\n");
213                         return;
214                 }
215                 evtimer_set(&monitor_event, monitor_cb, cl);
216                 tv.tv_sec = 0;
217                 tv.tv_usec = 0;
218                 evtimer_add(&monitor_event, &tv);
219                 monitor_running = 1;
220                 monitor_current = LIST_FIRST(&monitor_list);
221         }
222         else if (!strcmp(res->action, "end")) {
223                 if (monitor_running == 0) {
224                         printf("not running\n");
225                         return;
226                 }
227                 monitor_running = 0;
228                 evtimer_del(&monitor_event);
229         }
230 }
231
232 cmdline_parse_token_string_t cmd_monitor_monitor =
233         TOKEN_STRING_INITIALIZER(struct cmd_monitor_result, monitor, "monitor");
234 cmdline_parse_token_string_t cmd_monitor_action =
235         TOKEN_STRING_INITIALIZER(struct cmd_monitor_result, action,
236                                  "show#start#end");
237
238 cmdline_parse_inst_t cmd_monitor = {
239         .f = cmd_monitor_parsed,  /* function to call */
240         .data = NULL,      /* 2nd arg of func */
241         .help_str = "start/stop/show current monitoring",
242         .tokens = {        /* token list, NULL terminated */
243                 (void *)&cmd_monitor_monitor,
244                 (void *)&cmd_monitor_action,
245                 NULL,
246         },
247 };
248
249 /* ************* */
250
251 /* this structure is filled when cmd_monitor_add is parsed successfully */
252 struct cmd_monitor_add_result {
253         cmdline_fixed_string_t monitor;
254         cmdline_fixed_string_t action;
255         struct xbee_atcmd *cmd;
256 };
257
258 /* function called when cmd_monitor_add is parsed successfully */
259 static void cmd_monitor_add_parsed(void *parsed_result, struct cmdline *cl,
260                                    void *data)
261 {
262         struct cmd_monitor_add_result *res = parsed_result;
263         struct monitor_reg *m;
264
265         LIST_FOREACH(m, &monitor_list, next) {
266                 if (!strcmp(m->desc, res->cmd->desc))
267                         break;
268         }
269
270         if (m != NULL) {
271                 printf("already exist\n");
272                 return;
273         }
274
275         m = malloc(sizeof(*m));
276         if (m == NULL) {
277                 printf("no mem\n");
278                 return;
279         }
280
281         m->desc = res->cmd->desc;
282         m->atcmd = res->cmd->name;
283         LIST_INSERT_HEAD(&monitor_list, m, next);
284         monitor_count ++;
285 }
286
287 cmdline_parse_token_string_t cmd_monitor_add_monitor_add =
288         TOKEN_STRING_INITIALIZER(struct cmd_monitor_add_result, monitor,
289                                  "monitor");
290 cmdline_parse_token_string_t cmd_monitor_add_action =
291         TOKEN_STRING_INITIALIZER(struct cmd_monitor_add_result, action,
292                                  "add");
293 parse_token_atcmd_t cmd_monitor_add_atcmd =
294         TOKEN_ATCMD_INITIALIZER(struct cmd_monitor_add_result, cmd, &xbee_dev,
295                                 XBEE_ATCMD_F_READ, XBEE_ATCMD_F_READ);
296
297
298 cmdline_parse_inst_t cmd_monitor_add = {
299         .f = cmd_monitor_add_parsed,  /* function to call */
300         .data = NULL,      /* 2nd arg of func */
301         .help_str = "add a register in monitor list",
302         .tokens = {        /* token list, NULL terminated */
303                 (void *)&cmd_monitor_add_monitor_add,
304                 (void *)&cmd_monitor_add_action,
305                 (void *)&cmd_monitor_add_atcmd,
306                 NULL,
307         },
308 };
309
310 /* ************* */
311
312 /* this structure is filled when cmd_monitor_period is parsed successfully */
313 struct cmd_monitor_period_result {
314         cmdline_fixed_string_t monitor;
315         cmdline_fixed_string_t action;
316         uint32_t period;
317 };
318
319 /* function called when cmd_monitor_period is parsed successfully */
320 static void cmd_monitor_period_parsed(void *parsed_result, struct cmdline *cl,
321                                    void *data)
322 {
323         struct cmd_monitor_period_result *res = parsed_result;
324
325         if (res->period < 100) {
326                 printf("error, minimum period is 100 ms\n");
327                 return;
328         }
329
330         monitor_period_ms = res->period;
331 }
332
333 cmdline_parse_token_string_t cmd_monitor_period_monitor_period =
334         TOKEN_STRING_INITIALIZER(struct cmd_monitor_period_result, monitor,
335                                  "monitor");
336 cmdline_parse_token_string_t cmd_monitor_period_action =
337         TOKEN_STRING_INITIALIZER(struct cmd_monitor_period_result, action,
338                                  "period");
339 cmdline_parse_token_num_t cmd_monitor_period_period =
340         TOKEN_NUM_INITIALIZER(struct cmd_monitor_period_result, period, UINT32);
341
342
343 cmdline_parse_inst_t cmd_monitor_period = {
344         .f = cmd_monitor_period_parsed,  /* function to call */
345         .data = NULL,      /* 2nd arg of func */
346         .help_str = "set register monitoring period",
347         .tokens = {        /* token list, NULL terminated */
348                 (void *)&cmd_monitor_period_monitor_period,
349                 (void *)&cmd_monitor_period_action,
350                 (void *)&cmd_monitor_period_period,
351                 NULL,
352         },
353 };
354
355 /* ************* */
356
357 /* this structure is filled when cmd_monitor_del is parsed successfully */
358 struct cmd_monitor_del_result {
359         cmdline_fixed_string_t monitor;
360         cmdline_fixed_string_t action;
361         struct monitor_reg *m;
362 };
363
364 /* function called when cmd_monitor_del is parsed successfully */
365 static void cmd_monitor_del_parsed(void *parsed_result, struct cmdline *cl,
366                                    void *data)
367 {
368         struct cmd_monitor_del_result *res = parsed_result;
369
370         monitor_current = LIST_NEXT(res->m, next);
371         LIST_REMOVE(res->m, next);
372         free(res->m);
373         monitor_count --;
374         if (monitor_count == 0) {
375                 printf("Disable monitoring, no more event\n");
376                 evtimer_del(&monitor_event);
377                 monitor_running = 0;
378                 return;
379         }
380 }
381
382 cmdline_parse_token_string_t cmd_monitor_del_monitor_del =
383         TOKEN_STRING_INITIALIZER(struct cmd_monitor_del_result, monitor,
384                                  "monitor");
385 cmdline_parse_token_string_t cmd_monitor_del_action =
386         TOKEN_STRING_INITIALIZER(struct cmd_monitor_del_result, action,
387                                  "del");
388 parse_token_monitor_t cmd_monitor_del_atcmd =
389         TOKEN_MONITOR_INITIALIZER(struct cmd_monitor_del_result, m,
390                                   &monitor_list);
391
392
393 cmdline_parse_inst_t cmd_monitor_del = {
394         .f = cmd_monitor_del_parsed,  /* function to call */
395         .data = NULL,      /* 2nd arg of func */
396         .help_str = "del a register in monitor list",
397         .tokens = {        /* token list, NULL terminated */
398                 (void *)&cmd_monitor_del_monitor_del,
399                 (void *)&cmd_monitor_del_action,
400                 (void *)&cmd_monitor_del_atcmd,
401                 NULL,
402         },
403 };
404
405 /* ************* */
406
407 /* this structure is filled when cmd_range is parsed successfully */
408 struct cmd_range_result {
409         cmdline_fixed_string_t range;
410         cmdline_fixed_string_t action;
411 };
412
413 /* function called when cmd_range is parsed successfully */
414 static void cmd_range_parsed(void *parsed_result, struct cmdline *cl,
415                                void *data)
416 {
417         struct cmd_range_result *res = parsed_result;
418
419         if (!strcmp(res->action, "show")) {
420                 printf("range infos:\n");
421                 printf("  range period %d\n", range_period_ms);
422                 printf("  range count %d\n", range_count);
423                 printf("  range powermask 0x%x\n", range_powermask);
424                 printf("  range dstaddr %"PRIx64"\n", range_dstaddr);
425                 if (range_running)
426                         printf("  range test is running\n");
427                 else
428                         printf("  range test is not running\n");
429         }
430         else if (!strcmp(res->action, "start")) {
431                 struct timeval tv;
432                 if (range_running) {
433                         printf("already running\n");
434                         return;
435                 }
436                 range_cur_count = range_count;
437                 evtimer_set(&range_event, range_cb, cl);
438                 tv.tv_sec = 0;
439                 tv.tv_usec = 0;
440                 evtimer_add(&range_event, &tv);
441                 range_running = 1;
442         }
443         else if (!strcmp(res->action, "end")) {
444                 if (range_running == 0) {
445                         printf("not running\n");
446                         return;
447                 }
448                 range_running = 0;
449                 evtimer_del(&range_event);
450         }
451 }
452
453 cmdline_parse_token_string_t cmd_range_range =
454         TOKEN_STRING_INITIALIZER(struct cmd_range_result, range, "range");
455 cmdline_parse_token_string_t cmd_range_action =
456         TOKEN_STRING_INITIALIZER(struct cmd_range_result, action,
457                                  "show#start#end");
458
459 cmdline_parse_inst_t cmd_range = {
460         .f = cmd_range_parsed,  /* function to call */
461         .data = NULL,      /* 2nd arg of func */
462         .help_str = "start/stop/show current rangeing",
463         .tokens = {        /* token list, NULL terminated */
464                 (void *)&cmd_range_range,
465                 (void *)&cmd_range_action,
466                 NULL,
467         },
468 };
469
470 /* ************* */
471
472 /* this structure is filled when cmd_range_period is parsed successfully */
473 struct cmd_range_period_result {
474         cmdline_fixed_string_t range;
475         cmdline_fixed_string_t action;
476         uint32_t period;
477 };
478
479 /* function called when cmd_range_period is parsed successfully */
480 static void cmd_range_period_parsed(void *parsed_result, struct cmdline *cl,
481                                    void *data)
482 {
483         struct cmd_range_period_result *res = parsed_result;
484
485         if (res->period < 10) {
486                 printf("error, minimum period is 10 ms\n");
487                 return;
488         }
489
490         range_period_ms = res->period;
491 }
492
493 cmdline_parse_token_string_t cmd_range_period_range_period =
494         TOKEN_STRING_INITIALIZER(struct cmd_range_period_result, range,
495                                  "range");
496 cmdline_parse_token_string_t cmd_range_period_action =
497         TOKEN_STRING_INITIALIZER(struct cmd_range_period_result, action,
498                                  "period");
499 cmdline_parse_token_num_t cmd_range_period_period =
500         TOKEN_NUM_INITIALIZER(struct cmd_range_period_result, period, UINT32);
501
502
503 cmdline_parse_inst_t cmd_range_period = {
504         .f = cmd_range_period_parsed,  /* function to call */
505         .data = NULL,      /* 2nd arg of func */
506         .help_str = "set range test period",
507         .tokens = {        /* token list, NULL terminated */
508                 (void *)&cmd_range_period_range_period,
509                 (void *)&cmd_range_period_action,
510                 (void *)&cmd_range_period_period,
511                 NULL,
512         },
513 };
514
515 /* ************* */
516
517 /* this structure is filled when cmd_range_count is parsed successfully */
518 struct cmd_range_count_result {
519         cmdline_fixed_string_t range;
520         cmdline_fixed_string_t action;
521         uint32_t count;
522 };
523
524 /* function called when cmd_range_count is parsed successfully */
525 static void cmd_range_count_parsed(void *parsed_result, struct cmdline *cl,
526                                    void *data)
527 {
528         struct cmd_range_count_result *res = parsed_result;
529         range_count = res->count;
530 }
531
532 cmdline_parse_token_string_t cmd_range_count_range_count =
533         TOKEN_STRING_INITIALIZER(struct cmd_range_count_result, range,
534                                  "range");
535 cmdline_parse_token_string_t cmd_range_count_action =
536         TOKEN_STRING_INITIALIZER(struct cmd_range_count_result, action,
537                                  "count");
538 cmdline_parse_token_num_t cmd_range_count_count =
539         TOKEN_NUM_INITIALIZER(struct cmd_range_count_result, count, UINT32);
540
541
542 cmdline_parse_inst_t cmd_range_count = {
543         .f = cmd_range_count_parsed,  /* function to call */
544         .data = NULL,      /* 2nd arg of func */
545         .help_str = "set range test count",
546         .tokens = {        /* token list, NULL terminated */
547                 (void *)&cmd_range_count_range_count,
548                 (void *)&cmd_range_count_action,
549                 (void *)&cmd_range_count_count,
550                 NULL,
551         },
552 };
553
554 /* ************* */
555
556 /* this structure is filled when cmd_range_powermask is parsed successfully */
557 struct cmd_range_powermask_result {
558         cmdline_fixed_string_t range;
559         cmdline_fixed_string_t action;
560         uint8_t powermask;
561 };
562
563 /* function called when cmd_range_powermask is parsed successfully */
564 static void cmd_range_powermask_parsed(void *parsed_result, struct cmdline *cl,
565                                    void *data)
566 {
567         struct cmd_range_powermask_result *res = parsed_result;
568         range_powermask = res->powermask;
569 }
570
571 cmdline_parse_token_string_t cmd_range_powermask_range_powermask =
572         TOKEN_STRING_INITIALIZER(struct cmd_range_powermask_result, range,
573                                  "range");
574 cmdline_parse_token_string_t cmd_range_powermask_action =
575         TOKEN_STRING_INITIALIZER(struct cmd_range_powermask_result, action,
576                                  "powermask");
577 cmdline_parse_token_num_t cmd_range_powermask_powermask =
578         TOKEN_NUM_INITIALIZER(struct cmd_range_powermask_result, powermask,
579                               UINT8);
580
581
582 cmdline_parse_inst_t cmd_range_powermask = {
583         .f = cmd_range_powermask_parsed,  /* function to call */
584         .data = NULL,      /* 2nd arg of func */
585         .help_str = "set range test powermask",
586         .tokens = {        /* token list, NULL terminated */
587                 (void *)&cmd_range_powermask_range_powermask,
588                 (void *)&cmd_range_powermask_action,
589                 (void *)&cmd_range_powermask_powermask,
590                 NULL,
591         },
592 };
593
594 /* ************* */
595
596 /* this structure is filled when cmd_range_dstaddr is parsed successfully */
597 struct cmd_range_dstaddr_result {
598         cmdline_fixed_string_t range;
599         cmdline_fixed_string_t action;
600         uint64_t dstaddr;
601 };
602
603 /* function called when cmd_range_dstaddr is parsed successfully */
604 static void cmd_range_dstaddr_parsed(void *parsed_result, struct cmdline *cl,
605                                      void *data)
606 {
607         struct cmd_range_dstaddr_result *res = parsed_result;
608
609         range_dstaddr = res->dstaddr;
610 }
611
612 cmdline_parse_token_string_t cmd_range_dstaddr_range_dstaddr =
613         TOKEN_STRING_INITIALIZER(struct cmd_range_dstaddr_result, range,
614                                  "range");
615 cmdline_parse_token_string_t cmd_range_dstaddr_action =
616         TOKEN_STRING_INITIALIZER(struct cmd_range_dstaddr_result, action,
617                                  "dstaddr");
618 cmdline_parse_token_num_t cmd_range_dstaddr_dstaddr =
619         TOKEN_NUM_INITIALIZER(struct cmd_range_dstaddr_result, dstaddr, UINT64);
620
621
622 cmdline_parse_inst_t cmd_range_dstaddr = {
623         .f = cmd_range_dstaddr_parsed,  /* function to call */
624         .data = NULL,      /* 2nd arg of func */
625         .help_str = "set register rangeing dstaddr",
626         .tokens = {        /* token list, NULL terminated */
627                 (void *)&cmd_range_dstaddr_range_dstaddr,
628                 (void *)&cmd_range_dstaddr_action,
629                 (void *)&cmd_range_dstaddr_dstaddr,
630                 NULL,
631         },
632 };
633
634 /* ************* */
635
636 /* this structure is filled when cmd_rc_send is parsed successfully */
637 struct cmd_rc_send_result {
638         cmdline_fixed_string_t rc_send;
639         cmdline_fixed_string_t action;
640 };
641
642 /* function called when cmd_rc_send is parsed successfully */
643 static void cmd_rc_send_parsed(void *parsed_result, struct cmdline *cl,
644                                void *data)
645 {
646         struct cmd_rc_send_result *res = parsed_result;
647
648         if (!strcmp(res->action, "show"))
649                 ;//XXX
650         else if (!strcmp(res->action, "start")) {
651                 struct timeval tv;
652                 if (rc_send_running) {
653                         printf("already running\n");
654                         return;
655                 }
656                 evtimer_set(&rc_send_event, rc_send_cb, cl);
657                 tv.tv_sec = 0;
658                 tv.tv_usec = 0;
659                 evtimer_add(&rc_send_event, &tv);
660                 rc_send_running = 1;
661         }
662         else if (!strcmp(res->action, "end")) {
663                 if (rc_send_running == 0) {
664                         printf("not running\n");
665                         return;
666                 }
667                 rc_send_running = 0;
668                 evtimer_del(&rc_send_event);
669         }
670 }
671
672 cmdline_parse_token_string_t cmd_rc_send_rc_send =
673         TOKEN_STRING_INITIALIZER(struct cmd_rc_send_result, rc_send, "rc_send");
674 cmdline_parse_token_string_t cmd_rc_send_action =
675         TOKEN_STRING_INITIALIZER(struct cmd_rc_send_result, action,
676                                  "show#start#end");
677
678 cmdline_parse_inst_t cmd_rc_send = {
679         .f = cmd_rc_send_parsed,  /* function to call */
680         .data = NULL,      /* 2nd arg of func */
681         .help_str = "start/stop/show current rc_sending",
682         .tokens = {        /* token list, NULL terminated */
683                 (void *)&cmd_rc_send_rc_send,
684                 (void *)&cmd_rc_send_action,
685                 NULL,
686         },
687 };
688
689 /* ************* */
690
691 /* this structure is filled when cmd_rc_send_period is parsed successfully */
692 struct cmd_rc_send_period_result {
693         cmdline_fixed_string_t rc_send;
694         cmdline_fixed_string_t action;
695         uint32_t period;
696 };
697
698 /* function called when cmd_rc_send_period is parsed successfully */
699 static void cmd_rc_send_period_parsed(void *parsed_result, struct cmdline *cl,
700                                    void *data)
701 {
702         struct cmd_rc_send_period_result *res = parsed_result;
703
704         if (res->period < 10) {
705                 printf("error, minimum period is 10 ms\n");
706                 return;
707         }
708
709         rc_send_period_ms = res->period;
710 }
711
712 cmdline_parse_token_string_t cmd_rc_send_period_rc_send_period =
713         TOKEN_STRING_INITIALIZER(struct cmd_rc_send_period_result, rc_send,
714                                  "rc_send");
715 cmdline_parse_token_string_t cmd_rc_send_period_action =
716         TOKEN_STRING_INITIALIZER(struct cmd_rc_send_period_result, action,
717                                  "period");
718 cmdline_parse_token_num_t cmd_rc_send_period_period =
719         TOKEN_NUM_INITIALIZER(struct cmd_rc_send_period_result, period, UINT32);
720
721
722 cmdline_parse_inst_t cmd_rc_send_period = {
723         .f = cmd_rc_send_period_parsed,  /* function to call */
724         .data = NULL,      /* 2nd arg of func */
725         .help_str = "set register rc_sending period",
726         .tokens = {        /* token list, NULL terminated */
727                 (void *)&cmd_rc_send_period_rc_send_period,
728                 (void *)&cmd_rc_send_period_action,
729                 (void *)&cmd_rc_send_period_period,
730                 NULL,
731         },
732 };
733
734 /* ************* */
735
736 /* this structure is filled when cmd_rc_send_dstaddr is parsed successfully */
737 struct cmd_rc_send_dstaddr_result {
738         cmdline_fixed_string_t rc_send;
739         cmdline_fixed_string_t action;
740         uint64_t dstaddr;
741 };
742
743 /* function called when cmd_rc_send_dstaddr is parsed successfully */
744 static void cmd_rc_send_dstaddr_parsed(void *parsed_result, struct cmdline *cl,
745                                      void *data)
746 {
747         struct cmd_rc_send_dstaddr_result *res = parsed_result;
748
749         rc_send_dstaddr = res->dstaddr;
750 }
751
752 cmdline_parse_token_string_t cmd_rc_send_dstaddr_rc_send_dstaddr =
753         TOKEN_STRING_INITIALIZER(struct cmd_rc_send_dstaddr_result, rc_send,
754                                  "rc_send");
755 cmdline_parse_token_string_t cmd_rc_send_dstaddr_action =
756         TOKEN_STRING_INITIALIZER(struct cmd_rc_send_dstaddr_result, action,
757                                  "dstaddr");
758 cmdline_parse_token_num_t cmd_rc_send_dstaddr_dstaddr =
759         TOKEN_NUM_INITIALIZER(struct cmd_rc_send_dstaddr_result, dstaddr, UINT64);
760
761
762 cmdline_parse_inst_t cmd_rc_send_dstaddr = {
763         .f = cmd_rc_send_dstaddr_parsed,  /* function to call */
764         .data = NULL,      /* 2nd arg of func */
765         .help_str = "set register rc_sending dstaddr",
766         .tokens = {        /* token list, NULL terminated */
767                 (void *)&cmd_rc_send_dstaddr_rc_send_dstaddr,
768                 (void *)&cmd_rc_send_dstaddr_action,
769                 (void *)&cmd_rc_send_dstaddr_dstaddr,
770                 NULL,
771         },
772 };
773
774
775
776 /* ************* */
777
778 /* this structure is filled when cmd_ping is parsed successfully */
779 struct cmd_ping_result {
780         cmdline_fixed_string_t ping;
781 };
782
783 /* function called when cmd_ping is parsed successfully */
784 static void cmd_ping_parsed(void *parsed_result, struct cmdline *cl, void *data)
785 {
786         xbeeapp_send_atcmd("VL", NULL, 0, 1, NULL, NULL);
787 }
788
789 cmdline_parse_token_string_t cmd_ping_ping =
790         TOKEN_STRING_INITIALIZER(struct cmd_ping_result, ping, "ping");
791
792 cmdline_parse_inst_t cmd_ping = {
793         .f = cmd_ping_parsed,  /* function to call */
794         .data = NULL,      /* 2nd arg of func */
795         .help_str = "Send a ping to the xbee device",
796         .tokens = {        /* token list, NULL terminated */
797                 (void *)&cmd_ping_ping,
798                 NULL,
799         },
800 };
801
802 /* ************* */
803
804 /* this structure is filled when cmd_raw is parsed successfully */
805 struct cmd_raw_result {
806         cmdline_fixed_string_t raw;
807 };
808
809 /* function called when cmd_raw is parsed successfully */
810 static void cmd_raw_parsed(void *parsed_result, struct cmdline *cl, void *data)
811 {
812         printf("switched to raw mode, CTRL-D to exit\n");
813         rdline_stop(&cl->rdl); /* don't display prompt when return */
814         xbee_raw = 1;
815 }
816
817 cmdline_parse_token_string_t cmd_raw_raw =
818         TOKEN_STRING_INITIALIZER(struct cmd_raw_result, raw, "raw");
819
820 cmdline_parse_inst_t cmd_raw = {
821         .f = cmd_raw_parsed,  /* function to call */
822         .data = NULL,      /* 2nd arg of func */
823         .help_str = "Switch to raw mode",
824         .tokens = {        /* token list, NULL terminated */
825                 (void *)&cmd_raw_raw,
826                 NULL,
827         },
828 };
829
830 /* ************* */
831
832 /* this structure is filled when cmd_dump is parsed successfully */
833 struct cmd_dump_result {
834         cmdline_fixed_string_t dump;
835         cmdline_fixed_string_t onoff;
836 };
837
838 /* function called when cmd_dump is parsed successfully */
839 static void cmd_dump_parsed(void *parsed_result, struct cmdline *cl, void *data)
840 {
841         struct cmd_dump_result *res = parsed_result;
842         if (!strcmp(res->onoff, "on"))
843                 xbee_hexdump = 1;
844         else
845                 xbee_hexdump = 0;
846 }
847
848 cmdline_parse_token_string_t cmd_dump_dump =
849         TOKEN_STRING_INITIALIZER(struct cmd_dump_result, dump, "dump");
850
851 cmdline_parse_token_string_t cmd_dump_onoff =
852         TOKEN_STRING_INITIALIZER(struct cmd_dump_result, onoff, "on#off");
853
854 cmdline_parse_inst_t cmd_dump = {
855         .f = cmd_dump_parsed,  /* function to call */
856         .data = NULL,      /* 2nd arg of func */
857         .help_str = "enable/disable hexdump of received packets",
858         .tokens = {        /* token list, NULL terminated */
859                 (void *)&cmd_dump_dump,
860                 (void *)&cmd_dump_onoff,
861                 NULL,
862         },
863 };
864
865 /* ************* */
866
867 /* this structure is filled when cmd_debug is parsed successfully */
868 struct cmd_debug_result {
869         cmdline_fixed_string_t debug;
870         cmdline_fixed_string_t onoff;
871 };
872
873 /* function called when cmd_debug is parsed successfully */
874 static void cmd_debug_parsed(void *parsed_result, struct cmdline *cl, void *data)
875 {
876         struct cmd_debug_result *res = parsed_result;
877         if (!strcmp(res->onoff, "on"))
878                 xbee_debug = 1;
879         else
880                 xbee_debug = 0;
881 }
882
883 cmdline_parse_token_string_t cmd_debug_debug =
884         TOKEN_STRING_INITIALIZER(struct cmd_debug_result, debug, "debug");
885
886 cmdline_parse_token_string_t cmd_debug_onoff =
887         TOKEN_STRING_INITIALIZER(struct cmd_debug_result, onoff, "on#off");
888
889 cmdline_parse_inst_t cmd_debug = {
890         .f = cmd_debug_parsed,  /* function to call */
891         .data = NULL,      /* 2nd arg of func */
892         .help_str = "enable/disable additionnal debug",
893         .tokens = {        /* token list, NULL terminated */
894                 (void *)&cmd_debug_debug,
895                 (void *)&cmd_debug_onoff,
896                 NULL,
897         },
898 };
899
900 /* ************* */
901
902 /* this structure is filled when cmd_help is parsed successfully */
903 struct cmd_help_result {
904         cmdline_fixed_string_t help;
905         struct xbee_atcmd *cmd;
906 };
907
908 /* function called when cmd_help is parsed successfully */
909 static void cmd_help_parsed(void *parsed_result, struct cmdline *cl,
910                             void *data)
911 {
912         struct cmd_help_result *res = parsed_result;
913         int type;
914
915         type = (res->cmd->flags & (XBEE_ATCMD_F_READ | XBEE_ATCMD_F_WRITE));
916         switch (type) {
917                 case XBEE_ATCMD_F_READ:
918                         printf("Read-only\n");
919                         break;
920                 case XBEE_ATCMD_F_WRITE:
921                         printf("Write-only\n");
922                         break;
923                 default:
924                         printf("Read-write\n");
925                         break;
926         }
927         if (res->cmd->flags & XBEE_ATCMD_F_PARAM_NONE)
928                 printf("No argument\n");
929         else if (res->cmd->flags & XBEE_ATCMD_F_PARAM_U8)
930                 printf("Register is unsigned 8 bits\n");
931         else if (res->cmd->flags & XBEE_ATCMD_F_PARAM_U16)
932                 printf("Register is unsigned 16 bits\n");
933         else if (res->cmd->flags & XBEE_ATCMD_F_PARAM_U32)
934                 printf("Register is unsigned 32 bits\n");
935         else if (res->cmd->flags & XBEE_ATCMD_F_PARAM_S16)
936                 printf("Register is signed 16 bits\n");
937         else if (res->cmd->flags & XBEE_ATCMD_F_PARAM_STRING_20B)
938                 printf("Register is a 20 bytes string\n");
939         else
940                 printf("Unknown argument\n");
941
942         printf("%s\n", res->cmd->help);
943 }
944
945 cmdline_parse_token_string_t cmd_help_help =
946         TOKEN_STRING_INITIALIZER(struct cmd_help_result, help, "help");
947
948 parse_token_atcmd_t cmd_help_atcmd =
949         TOKEN_ATCMD_INITIALIZER(struct cmd_help_result, cmd, &xbee_dev,
950                                 0, 0);
951
952 cmdline_parse_inst_t cmd_help = {
953         .f = cmd_help_parsed,  /* function to call */
954         .data = NULL,      /* 2nd arg of func */
955         .help_str = "Help a register using an AT command",
956         .tokens = {        /* token list, NULL terminated */
957                 (void *)&cmd_help_help,
958                 (void *)&cmd_help_atcmd,
959                 NULL,
960         },
961 };
962
963 /* ************* */
964
965 /* this structure is filled when cmd_read is parsed successfully */
966 struct cmd_read_result {
967         cmdline_fixed_string_t read;
968         struct xbee_atcmd *cmd;
969 };
970
971 /* function called when cmd_read is parsed successfully */
972 static void cmd_read_parsed(void *parsed_result, struct cmdline *cl,
973                             void *data)
974 {
975         struct cmd_read_result *res = parsed_result;
976         xbeeapp_send_atcmd(res->cmd->name, NULL, 0, 1, NULL, NULL);
977 }
978
979 cmdline_parse_token_string_t cmd_read_read =
980         TOKEN_STRING_INITIALIZER(struct cmd_read_result, read, "read");
981
982 parse_token_atcmd_t cmd_read_atcmd =
983         TOKEN_ATCMD_INITIALIZER(struct cmd_read_result, cmd, &xbee_dev,
984                                 XBEE_ATCMD_F_READ, XBEE_ATCMD_F_READ);
985
986 cmdline_parse_inst_t cmd_read = {
987         .f = cmd_read_parsed,  /* function to call */
988         .data = NULL,      /* 2nd arg of func */
989         .help_str = "Read a register using an AT command",
990         .tokens = {        /* token list, NULL terminated */
991                 (void *)&cmd_read_read,
992                 (void *)&cmd_read_atcmd,
993                 NULL,
994         },
995 };
996
997 /* ************* */
998
999 /* this structure is filled when cmd_write is parsed successfully */
1000 struct cmd_write_result {
1001         cmdline_fixed_string_t write;
1002         struct xbee_atcmd *cmd;
1003         union {
1004                 uint8_t u8;
1005                 uint16_t u16;
1006                 uint32_t u32;
1007         };
1008 };
1009
1010 /* function called when cmd_write is parsed successfully */
1011 static void cmd_write_parsed(void *parsed_result, struct cmdline *cl,
1012                              void *data)
1013 {
1014         struct cmd_write_result *res = parsed_result;
1015         int len;
1016         void *param;
1017
1018         if (res->cmd->flags & XBEE_ATCMD_F_PARAM_NONE) {
1019                 len = 0;
1020                 param = NULL;
1021         }
1022         else if (res->cmd->flags & XBEE_ATCMD_F_PARAM_U8) {
1023                 len = sizeof(res->u8);
1024                 param = &res->u8;
1025         }
1026         else if (res->cmd->flags & XBEE_ATCMD_F_PARAM_U16) {
1027                 len = sizeof(res->u16);
1028                 res->u16 = htons(res->u16);
1029                 param = &res->u16;
1030         }
1031         else if (res->cmd->flags & XBEE_ATCMD_F_PARAM_U32) {
1032                 len = sizeof(res->u32);
1033                 res->u32 = htonl(res->u32);
1034                 param = &res->u32;
1035         }
1036         else {
1037                 printf("Unknown argument type\n");
1038                 return;
1039         }
1040         xbeeapp_send_atcmd(res->cmd->name, param, len, 1, NULL, NULL);
1041 }
1042
1043 cmdline_parse_token_string_t cmd_write_write =
1044         TOKEN_STRING_INITIALIZER(struct cmd_write_result, write,
1045                                  "write");
1046
1047 parse_token_atcmd_t cmd_write_none_atcmd =
1048         TOKEN_ATCMD_INITIALIZER(struct cmd_write_result, cmd,
1049                                 &xbee_dev,
1050                                 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_NONE,
1051                                 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_NONE);
1052
1053 cmdline_parse_inst_t cmd_write_none = {
1054         .f = cmd_write_parsed,  /* function to call */
1055         .data = NULL,      /* 2nd arg of func */
1056         .help_str = "Send an AT command (no argument)",
1057         .tokens = {        /* token list, NULL terminated */
1058                 (void *)&cmd_write_write,
1059                 (void *)&cmd_write_none_atcmd,
1060                 NULL,
1061         },
1062 };
1063
1064 parse_token_atcmd_t cmd_write_u8_atcmd =
1065         TOKEN_ATCMD_INITIALIZER(struct cmd_write_result, cmd,
1066                                 &xbee_dev,
1067                                 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U8,
1068                                 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U8);
1069
1070 cmdline_parse_token_num_t cmd_write_u8_u8 =
1071         TOKEN_NUM_INITIALIZER(struct cmd_write_result, u8, UINT8);
1072
1073 cmdline_parse_inst_t cmd_write_u8 = {
1074         .f = cmd_write_parsed,  /* function to call */
1075         .data = NULL,      /* 2nd arg of func */
1076         .help_str = "Write a 8 bits register using an AT command",
1077         .tokens = {        /* token list, NULL terminated */
1078                 (void *)&cmd_write_write,
1079                 (void *)&cmd_write_u8_atcmd,
1080                 (void *)&cmd_write_u8_u8,
1081                 NULL,
1082         },
1083 };
1084
1085 parse_token_atcmd_t cmd_write_u16_atcmd =
1086         TOKEN_ATCMD_INITIALIZER(struct cmd_write_result, cmd,
1087                                 &xbee_dev,
1088                                 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U16,
1089                                 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U16);
1090
1091 cmdline_parse_token_num_t cmd_write_u16_u16 =
1092         TOKEN_NUM_INITIALIZER(struct cmd_write_result, u16, UINT16);
1093
1094 cmdline_parse_inst_t cmd_write_u16 = {
1095         .f = cmd_write_parsed,  /* function to call */
1096         .data = NULL,      /* 2nd arg of func */
1097         .help_str = "Write a 16 bits register using an AT command",
1098         .tokens = {        /* token list, NULL terminated */
1099                 (void *)&cmd_write_write,
1100                 (void *)&cmd_write_u16_atcmd,
1101                 (void *)&cmd_write_u16_u16,
1102                 NULL,
1103         },
1104 };
1105
1106 parse_token_atcmd_t cmd_write_u32_atcmd =
1107         TOKEN_ATCMD_INITIALIZER(struct cmd_write_result, cmd,
1108                                 &xbee_dev,
1109                                 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U32,
1110                                 XBEE_ATCMD_F_WRITE | XBEE_ATCMD_F_PARAM_U32);
1111
1112 cmdline_parse_token_num_t cmd_write_u32_u32 =
1113         TOKEN_NUM_INITIALIZER(struct cmd_write_result, u32, UINT32);
1114
1115 cmdline_parse_inst_t cmd_write_u32 = {
1116         .f = cmd_write_parsed,  /* function to call */
1117         .data = NULL,      /* 2nd arg of func */
1118         .help_str = "Write a 32 bits register using an AT command",
1119         .tokens = {        /* token list, NULL terminated */
1120                 (void *)&cmd_write_write,
1121                 (void *)&cmd_write_u32_atcmd,
1122                 (void *)&cmd_write_u32_u32,
1123                 NULL,
1124         },
1125 };
1126
1127 /* ************* */
1128
1129 /* this structure is filled when cmd_sendmsg is parsed successfully */
1130 struct cmd_sendmsg_result {
1131         cmdline_fixed_string_t sendmsg;
1132         uint64_t addr;
1133         cmdline_fixed_string_t data;
1134 };
1135
1136 /* function called when cmd_sendmsg is parsed successfully */
1137 static void cmd_sendmsg_parsed(void *parsed_result, struct cmdline *cl,
1138                             void *data)
1139 {
1140         struct cmd_sendmsg_result *res = parsed_result;
1141         xbeeapp_send_msg(res->addr, res->data, strlen(res->data), 1);
1142 }
1143
1144 cmdline_parse_token_string_t cmd_sendmsg_sendmsg =
1145         TOKEN_STRING_INITIALIZER(struct cmd_sendmsg_result, sendmsg, "sendmsg");
1146
1147 cmdline_parse_token_num_t cmd_sendmsg_addr =
1148         TOKEN_NUM_INITIALIZER(struct cmd_sendmsg_result, addr, UINT64);
1149
1150 cmdline_parse_token_string_t cmd_sendmsg_data =
1151         TOKEN_STRING_INITIALIZER(struct cmd_sendmsg_result, data, NULL);
1152
1153 cmdline_parse_inst_t cmd_sendmsg = {
1154         .f = cmd_sendmsg_parsed,  /* function to call */
1155         .data = NULL,      /* 2nd arg of func */
1156         .help_str = "Send data to a node using its address",
1157         .tokens = {        /* token list, NULL terminated */
1158                 (void *)&cmd_sendmsg_sendmsg,
1159                 (void *)&cmd_sendmsg_addr,
1160                 (void *)&cmd_sendmsg_data,
1161                 NULL,
1162         },
1163 };
1164
1165 /* ************* */
1166
1167 /* this structure is filled when cmd_sendmsg_name is parsed successfully */
1168 struct cmd_sendmsg_name_result {
1169         cmdline_fixed_string_t sendmsg_name;
1170         struct xbee_neigh *neigh;
1171         cmdline_fixed_string_t data;
1172 };
1173
1174 /* function called when cmd_sendmsg_name is parsed successfully */
1175 static void cmd_sendmsg_name_parsed(void *parsed_result, struct cmdline *cl,
1176                             void *data)
1177 {
1178         struct cmd_sendmsg_name_result *res = parsed_result;
1179         xbeeapp_send_msg(res->neigh->addr, res->data, strlen(res->data), 1);
1180 }
1181
1182 cmdline_parse_token_string_t cmd_sendmsg_name_sendmsg_name =
1183         TOKEN_STRING_INITIALIZER(struct cmd_sendmsg_name_result, sendmsg_name,
1184                                  "sendmsg");
1185
1186 parse_token_neighbor_t cmd_sendmsg_name_neigh =
1187         TOKEN_NEIGHBOR_INITIALIZER(struct cmd_sendmsg_name_result, neigh,
1188                                    &xbee_dev);
1189
1190 cmdline_parse_token_string_t cmd_sendmsg_name_data =
1191         TOKEN_STRING_INITIALIZER(struct cmd_sendmsg_name_result, data, NULL);
1192
1193 cmdline_parse_inst_t cmd_sendmsg_name = {
1194         .f = cmd_sendmsg_name_parsed,  /* function to call */
1195         .data = NULL,      /* 2nd arg of func */
1196         .help_str = "Send data to a node using its name",
1197         .tokens = {        /* token list, NULL terminated */
1198                 (void *)&cmd_sendmsg_name_sendmsg_name,
1199                 (void *)&cmd_sendmsg_name_neigh,
1200                 (void *)&cmd_sendmsg_name_data,
1201                 NULL,
1202         },
1203 };
1204
1205 /* ************* */
1206
1207 struct cmd_neigh_del_result {
1208         cmdline_fixed_string_t cmd;
1209         cmdline_fixed_string_t action;
1210         struct xbee_neigh *neigh;
1211 };
1212
1213 static void cmd_neigh_del_parsed(void *parsed_result,
1214                                 struct cmdline *cl,
1215                                 void *data)
1216 {
1217         struct cmd_neigh_del_result *res = parsed_result;
1218         xbee_neigh_del(xbee_dev, res->neigh);
1219 }
1220
1221 cmdline_parse_token_string_t cmd_neigh_del_cmd =
1222         TOKEN_STRING_INITIALIZER(struct cmd_neigh_del_result, cmd, "neigh");
1223 cmdline_parse_token_string_t cmd_neigh_del_action =
1224         TOKEN_STRING_INITIALIZER(struct cmd_neigh_del_result, action, "del");
1225 parse_token_neighbor_t cmd_neigh_del_neigh =
1226         TOKEN_NEIGHBOR_INITIALIZER(struct cmd_neigh_del_result, neigh,
1227                                    &xbee_dev);
1228
1229 cmdline_parse_inst_t cmd_neigh_del = {
1230         .f = cmd_neigh_del_parsed,  /* function to call */
1231         .data = NULL,      /* 2nd arg of func */
1232         .help_str = "delete a neighbor",
1233         .tokens = {        /* token list, NULL terminated */
1234                 (void *)&cmd_neigh_del_cmd,
1235                 (void *)&cmd_neigh_del_action,
1236                 (void *)&cmd_neigh_del_neigh,
1237                 NULL,
1238         },
1239 };
1240
1241 /* ************* */
1242
1243 struct cmd_neigh_add_result {
1244         cmdline_fixed_string_t cmd;
1245         cmdline_fixed_string_t action;
1246         cmdline_fixed_string_t name;
1247         uint64_t addr;
1248 };
1249
1250 static void cmd_neigh_add_parsed(void *parsed_result,
1251                                 struct cmdline *cl,
1252                                 void *data)
1253 {
1254         struct cmd_neigh_add_result *res = parsed_result;
1255         if (xbee_neigh_add(xbee_dev, res->name, res->addr) == NULL)
1256                 printf("name or addr already exist\n");
1257 }
1258
1259 cmdline_parse_token_string_t cmd_neigh_add_cmd =
1260         TOKEN_STRING_INITIALIZER(struct cmd_neigh_add_result, cmd, "neigh");
1261 cmdline_parse_token_string_t cmd_neigh_add_action =
1262         TOKEN_STRING_INITIALIZER(struct cmd_neigh_add_result, action, "add");
1263 cmdline_parse_token_string_t cmd_neigh_add_name =
1264         TOKEN_STRING_INITIALIZER(struct cmd_neigh_add_result, name, NULL);
1265 cmdline_parse_token_num_t cmd_neigh_add_addr =
1266         TOKEN_NUM_INITIALIZER(struct cmd_neigh_add_result, addr, UINT64);
1267
1268 cmdline_parse_inst_t cmd_neigh_add = {
1269         .f = cmd_neigh_add_parsed,  /* function to call */
1270         .data = NULL,      /* 2nd arg of func */
1271         .help_str = "add a neighbor",
1272         .tokens = {        /* token list, NULL terminated */
1273                 (void *)&cmd_neigh_add_cmd,
1274                 (void *)&cmd_neigh_add_action,
1275                 (void *)&cmd_neigh_add_name,
1276                 (void *)&cmd_neigh_add_addr,
1277                 NULL,
1278         },
1279 };
1280
1281 /* ************* */
1282
1283 struct cmd_neigh_list_result {
1284         cmdline_fixed_string_t cmd;
1285         cmdline_fixed_string_t action;
1286 };
1287
1288 static void cmd_neigh_list_parsed(void *parsed_result,
1289                                 struct cmdline *cl,
1290                                 void *data)
1291 {
1292         struct xbee_neigh *neigh;
1293
1294         LIST_FOREACH(neigh, &xbee_dev->neigh_list, next) {
1295                 printf(" %s: 0x%"PRIx64"\n", neigh->name, neigh->addr);
1296         }
1297 }
1298
1299 cmdline_parse_token_string_t cmd_neigh_list_cmd =
1300         TOKEN_STRING_INITIALIZER(struct cmd_neigh_list_result, cmd, "neigh");
1301 cmdline_parse_token_string_t cmd_neigh_list_action =
1302         TOKEN_STRING_INITIALIZER(struct cmd_neigh_list_result, action, "list");
1303
1304 cmdline_parse_inst_t cmd_neigh_list = {
1305         .f = cmd_neigh_list_parsed,  /* function to call */
1306         .data = NULL,      /* 2nd arg of func */
1307         .help_str = "list all known neighbors",
1308         .tokens = {        /* token list, NULL terminated */
1309                 (void *)&cmd_neigh_list_cmd,
1310                 (void *)&cmd_neigh_list_action,
1311                 NULL,
1312         },
1313 };
1314
1315 /*******************/
1316
1317 struct cmd_logfile_result {
1318         cmdline_fixed_string_t logfile;
1319         cmdline_filename_t file;
1320 };
1321
1322 static void cmd_logfile_parsed(void *parsed_result,
1323                                struct cmdline *cl,
1324                                void *data)
1325 {
1326         if (xbee_logfile != NULL)
1327                 fclose(xbee_logfile);
1328         xbee_logfile = fopen(xbee_logfilename, "a");
1329         if (xbee_logfile == NULL)
1330                 printf("cannot open file: %s\n", strerror(errno));
1331         fprintf(xbee_logfile, "-------------------start\n");
1332         printf("enabling log\n");
1333 }
1334
1335 cmdline_parse_token_string_t cmd_logfile_logfile =
1336         TOKEN_STRING_INITIALIZER(struct cmd_logfile_result, logfile, "logfile");
1337
1338 cmdline_parse_token_file_t cmd_logfile_file =
1339         TOKEN_FILE_INITIALIZER(struct cmd_logfile_result, file,
1340                                PARSE_FILE_F_CREATE);
1341
1342 cmdline_parse_inst_t cmd_logfile = {
1343         .f = cmd_logfile_parsed,  /* function to call */
1344         .data = NULL,      /* 2nd arg of func */
1345         .help_str = "<logfile FILE> set log file",
1346         .tokens = {        /* token list, NULL terminated */
1347                 (void *)&cmd_logfile_logfile,
1348                 (void *)&cmd_logfile_file,
1349                 NULL,
1350         },
1351 };
1352
1353 /* ************* */
1354
1355 /* this structure is filled when cmd_log is parsed successfully */
1356 struct cmd_log_result {
1357         cmdline_fixed_string_t log;
1358         cmdline_fixed_string_t onoff;
1359 };
1360
1361 /* function called when cmd_log is parsed successfully */
1362 static void cmd_log_parsed(void *parsed_result, struct cmdline *cl, void *data)
1363 {
1364         struct cmd_log_result *res = parsed_result;
1365         if (!strcmp(res->onoff, "on") && xbee_logfile == NULL) {
1366                 xbee_logfile = fopen(xbee_logfilename, "a");
1367                 if (xbee_logfile == NULL)
1368                         printf("cannot open file: %s\n", strerror(errno));
1369                 fprintf(xbee_logfile, "-------------------start\n");
1370         }
1371         else if (!strcmp(res->onoff, "off") && xbee_logfile != NULL) {
1372                 fclose(xbee_logfile);
1373                 xbee_logfile = NULL;
1374         }
1375 }
1376
1377 cmdline_parse_token_string_t cmd_log_log =
1378         TOKEN_STRING_INITIALIZER(struct cmd_log_result, log, "log");
1379
1380 cmdline_parse_token_string_t cmd_log_onoff =
1381         TOKEN_STRING_INITIALIZER(struct cmd_log_result, onoff, "on#off");
1382
1383 cmdline_parse_inst_t cmd_log = {
1384         .f = cmd_log_parsed,  /* function to call */
1385         .data = NULL,      /* 2nd arg of func */
1386         .help_str = "enable/disable hexlog of received packets",
1387         .tokens = {        /* token list, NULL terminated */
1388                 (void *)&cmd_log_log,
1389                 (void *)&cmd_log_onoff,
1390                 NULL,
1391         },
1392 };
1393
1394
1395 /*******************/
1396
1397 struct cmd_saveconfig_result {
1398         cmdline_fixed_string_t saveconfig;
1399         cmdline_filename_t file;
1400 };
1401
1402 static void cmd_saveconfig_parsed(void *parsed_result,
1403                                struct cmdline *cl,
1404                                void *data)
1405 {
1406         struct cmd_saveconfig_result *res = parsed_result;
1407
1408         if (xbeeapp_dump_config(res->file) < 0)
1409                 printf("cannot save config\n");
1410 }
1411
1412 cmdline_parse_token_string_t cmd_saveconfig_saveconfig =
1413         TOKEN_STRING_INITIALIZER(struct cmd_saveconfig_result, saveconfig,
1414                                  "saveconfig");
1415
1416 cmdline_parse_token_file_t cmd_saveconfig_file =
1417         TOKEN_FILE_INITIALIZER(struct cmd_saveconfig_result, file,
1418                                PARSE_FILE_F_CREATE);
1419
1420 cmdline_parse_inst_t cmd_saveconfig = {
1421         .f = cmd_saveconfig_parsed,  /* function to call */
1422         .data = NULL,      /* 2nd arg of func */
1423         .help_str = "<saveconfig FILE> set log file",
1424         .tokens = {        /* token list, NULL terminated */
1425                 (void *)&cmd_saveconfig_saveconfig,
1426                 (void *)&cmd_saveconfig_file,
1427                 NULL,
1428         },
1429 };
1430
1431 /*******************/
1432
1433 struct cmd_loadconfig_result {
1434         cmdline_fixed_string_t loadconfig;
1435         cmdline_filename_t file;
1436 };
1437
1438 static void cmd_loadconfig_parsed(void *parsed_result,
1439                                struct cmdline *cl,
1440                                void *data)
1441 {
1442 }
1443
1444 cmdline_parse_token_string_t cmd_loadconfig_loadconfig =
1445         TOKEN_STRING_INITIALIZER(struct cmd_loadconfig_result, loadconfig,
1446                                  "loadconfig");
1447
1448 cmdline_parse_token_file_t cmd_loadconfig_file =
1449         TOKEN_FILE_INITIALIZER(struct cmd_loadconfig_result, file,
1450                                PARSE_FILE_F_CREATE);
1451
1452 cmdline_parse_inst_t cmd_loadconfig = {
1453         .f = cmd_loadconfig_parsed,  /* function to call */
1454         .data = NULL,      /* 2nd arg of func */
1455         .help_str = "<loadconfig FILE> set log file",
1456         .tokens = {        /* token list, NULL terminated */
1457                 (void *)&cmd_loadconfig_loadconfig,
1458                 (void *)&cmd_loadconfig_file,
1459                 NULL,
1460         },
1461 };
1462
1463 /**********************************************************/
1464 /**********************************************************/
1465 /****** CONTEXT (list of instruction) */
1466
1467 /* in progmem */
1468 cmdline_parse_ctx_t main_ctx = {
1469         .name = "main",
1470         .insts = {
1471                 &cmd_stats,
1472                 &cmd_monitor,
1473                 &cmd_monitor_period,
1474                 &cmd_monitor_add,
1475                 &cmd_monitor_del,
1476                 &cmd_range,
1477                 &cmd_range_period,
1478                 &cmd_range_count,
1479                 &cmd_range_powermask,
1480                 &cmd_range_dstaddr,
1481                 &cmd_rc_send,
1482                 &cmd_rc_send_period,
1483                 &cmd_rc_send_dstaddr,
1484                 &cmd_ping,
1485                 &cmd_raw,
1486                 &cmd_dump,
1487                 &cmd_debug,
1488                 &cmd_help,
1489                 &cmd_read,
1490                 &cmd_write_none,
1491                 &cmd_write_u8,
1492                 &cmd_write_u16,
1493                 &cmd_write_u32,
1494                 &cmd_sendmsg,
1495                 &cmd_sendmsg_name,
1496                 &cmd_neigh_del,
1497                 &cmd_neigh_add,
1498                 &cmd_neigh_list,
1499                 &cmd_logfile,
1500                 &cmd_log,
1501                 &cmd_saveconfig,
1502                 &cmd_loadconfig,
1503                 NULL,
1504         },
1505 };