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