SingingCat  0
application
command-handler.c
Go to the documentation of this file.
1 #include <main-header.h>
2 #include <loader-api.h>
3 #include <user_app_exe.h>
4 #include <constants.h>
5 #include <function-instr.h>
6 #include "sc_time.h"
7 #include <baseinfo.h>
8 #include <streams.h>
9 #include <flashapp.h>
10 #include <fets.h>
11 #include <led.h>
12 #include <sensors/sensor.h>
13 #include <sensors/sensor_command.h>
14 #include <routing.h>
15 #include <route_command.h>
16 #include <forwarding.h>
17 #include "ti1101.h"
18 #include "user_app_info.h"
19 #include "user_app_exe.h"
20 //#include <bare-metal.h>
21 
22 static int dac_toggle_high = 0;
23 static int dac_toggle_low = 0;
24 static int dac_toggle_speed;
25 static int dac_toggle_cur;
26 static int dac_cur_value = 0;
27 static int dac_toggle_step = 0;
28 static byte dac_cur_dir = 0;
29 
30 static int strobe_relay = 0;
31 static int strobe_cur = 0;
32 static int strobe_repeat = 0;
33 static int strobe_timeout_on = 0;
34 static int strobe_timeout_off = 0;
35 static int strobe_state = 0;
36 #define MAX_PIN_STATES 5
37 static uint16_t pinstates[MAX_PIN_STATES]; // max 5 pins may be
52 // the delivery queue
53 
54 
56 extern int ack_ctr;
57 
58 static void restore_pin(int pin);
59 static void store_pin(int pin);
60 void list_modules(struct command *com);
61 void process_strobe_command(struct command *com);
62 void check_strobe();
63 void start_strobe(int relay, int ton, int toff, int repeat);
64 static void software_info(struct command *com);
65 static void installed_info(struct command *com);
66 static void button_pressed(struct command *com);
67 static void set_server_name(struct command *com);
68 static void set_sensor_server_name(struct command *com);
69 static void set_config(struct command *com);
77  memset(&pinstates, 0, sizeof(pinstates));
78 }
79 void setpin(struct command *com) {
80  int r;
81  int pin = atoi(get_arg(com, 0));
82  int state = atoi(get_arg(com, 1));
83 
84  if ((pin == 100) || (pin == 101)) {
85  fets_set_com(com);
86  return;
87  }
88  printf("setting pin %i to %i\r\n", pin, state);
89  if ((r = mculib_pin_out(MAIN_MCULIBHANDLE, pin, HAL_PIN_FASTEST))) {
90  printf("set-pin: failed to set pin %i to out: %i\r\n", pin, r);
91  return;
92  }
93  r = mculib_pin_set(MAIN_MCULIBHANDLE, pin, state);
94  if (r != 0) {
95  printf("set-pin: failed to set pin: %i\r\n", r);
96  }
97 }
101 static void completion(struct command *com, int result) {
102  if (result == 1) {
103  send_command_reply(com, COMFLAGS_ACK | COMFLAGS_SUCCESS);
104  return;
105  } else if (result == 2) {
106  send_command_reply(com, COMFLAGS_ACK);
107  return;
108  }
109 }
110 
119 int is_packet_for_us(struct command *com) {
120  char ownnode[10];
121  char othernode[10];
122 
123  node_to_str(config_get_ram_struct()->nodeid, ownnode);
124  if (!adr_isvalid(com->sender)) {
125  node_to_str(com->sender, othernode);
126  printf("Dropping packet: Invalid sender ID: %s\r\n", othernode);
127  return 0;
128  }
129  if (!adr_isvalid(com->recipient)) {
130  node_to_str(com->recipient, othernode);
131  printf("Dropping packet: Invalid recipient ID: %s\r\n", othernode);
132  return 0;
133  }
134  if (!adr_isvalid(com->target)) {
135  node_to_str(com->target, othernode);
136  printf("Dropping packet: Invalid target ID: %s\r\n", othernode);
137  return 0;
138  }
139  // check if packet is for ourselves
140  if (
141  (com->recipient == 0xFFFFFFFF)
142  || (com->target == 0xFFFFFFFF)
143  || (com->recipient == get_my_node_id())
144  ) {
145  return 1;
146  }
147 
148 
149  // not for ourselves - but to forward
150  node_to_str(com->recipient, othernode);
151  printf("comhandler: Forwarding packet to %s...\r\n", othernode);
152  int i = forward_packet(com);
153 
154  printf("forward result: %i\r\n", i);
155  return 0;
156 }
157 
158 void set_logging(struct command *com) {
159  int enable;
160  int newpos;
161 
162  enable = 0;
163  if (com->argctr > 0) {
164  enable = atoi(get_arg(com, 0));
165  }
166  if (com->argctr > 1) {
167  long node = ascii_parse_hex((const byte *)get_arg(com, 1), 8, &newpos);
168  logging_set_node(node);
169  config_set_log_node(node);
170  config_commit();
171  IPLOG("logging enabled\r\n");
172  }
173  if (enable) {
174  logging_on();
175  } else {
176  IPLOG("Disabling logging\r\n");
177  logging_off();
178  config_set_log_node(0);
179  config_commit();
180  }
181 }
182 void static inline xdelay_us(int us, int timeout) {
183  int jc = 0;
184  int x = us * timeout;
185 
186  while (jc < x) {
187  jc++;
188  }
189 }
190 
191 
196 void micro_strobe(struct command *com) {
197  int pin = atoi(get_arg(com, 0));
198  int timeout_on = atoi(get_arg(com, 1));
199  int timeout_off = atoi(get_arg(com, 2));
200  int repeat = atoi(get_arg(com, 3));
201  int us = atoi(get_arg(com, 4));
202  int i = 0;
203 
204  //long t = mculib_get_seconds_since_boot();
205  for (i = 0; i < repeat; i++) {
206  // long x = mculib_get_seconds_since_boot();
207  //if ( (x-t) > 10) {
208  // break;
209  //}
210  //avoid_watchdog();
211  mculib_pin_set(MAIN_MCULIBHANDLE, pin, 1);
212  xdelay_us(us, timeout_on);
213  mculib_pin_set(MAIN_MCULIBHANDLE, pin, 0);
214  xdelay_us(us, timeout_off);
215  }
216  send_command_reply(com, COMFLAGS_ACK | COMFLAGS_SUCCESS);
217  printf("Did strobe timeout_on=%i,timeout_off=%i...\r\n", timeout_on, timeout_off);
218 }
222 void factory_default(struct command *com) {
223  printf("Erasing config...\r\n");
224  config_erase();
225  loader_erase_config();
226  printf("Rebooting...\r\n");
227  reboot_fast();
228 }
229 
230 
231 
238  long res = config_get_ram_struct()->nodeid;
239 
240  if (!adr_isvalid(res)) {
241  return 0;
242  }
243  res = res & 0xFFFFFFFF; // ensure 32bit
244  return res;
245 }
246 
253 void setcloudtoken(struct command *com) {
254  if (com->argctr != 1) {
255  printf("Missing cloud token!\r\n");
256  send_command_reply(com, COMFLAGS_ACK);
257  return;
258  }
259  const char *token = get_arg(com, 0);
260 
261  if (token == NULL) {
262  printf("cloud token must not be NULL!\r\n");
263  send_command_reply(com, COMFLAGS_ACK);
264  return;
265  }
266  printf("Setting a cloud token\r\n");
267  config_set_cloud_token(token);
268  config_commit();
269  send_command_reply(com, COMFLAGS_ACK | COMFLAGS_SUCCESS);
270  //esp_cloudconnect("module-in.singingcat.net");
272 }
273 void forward_radio(struct command *com) {
274  int newpos;
275  long node = ascii_parse_hex((const byte *)get_arg(com, 0), 8, &newpos);
276 
277  ti1101_forward_radio(node);
278  send_command_reply(com, COMFLAGS_ACK | COMFLAGS_SUCCESS);
279 }
283 static void set_server_name(struct command *com) {
284  config_set_cloud_server(get_arg(com, 0));
285  send_command_reply(com, COMFLAGS_ACK | COMFLAGS_SUCCESS);
286  //send_command_reply(com, COMFLAGS_ACK);
287  printf("Command-handler: set new cloud server to %s\r\n", get_arg(com, 0));
288  esp_init();
289 }
293 static void set_sensor_server_name(struct command *com) {
294  if (com->argctr != 2) {
295  IPLOG("Error - need exactly 2 arguments to set_server_name, not %i\r\n", com->argctr);
296  send_command_reply(com, COMFLAGS_ACK);
297  return;
298  }
299  const char *srv = get_arg(com, 0);
300 
301  printf("Setting sensor server to \"%s\"\r\n", srv);
302  config_set_sensor_server(srv);
303  send_command_reply(com, COMFLAGS_ACK | COMFLAGS_SUCCESS);
304  config_commit();
305 }
309 void set_config_flag(struct command *com) {
310  if (com->argctr != 2) {
311  IPLOG("Error - need exactly 2 arguments to set_config_flag, not %i\r\n", com->argctr);
312  send_command_reply(com, COMFLAGS_ACK);
313  return;
314  }
315  int flag = atoi(get_arg(com, 0));
316  int value = atoi(get_arg(com, 1));
317 
318  config_set_flag(flag, value);
319  send_command_reply(com, COMFLAGS_ACK | COMFLAGS_SUCCESS);
320  config_commit();
321 }
325 void get_config_flags(struct command *com) {
326  struct command *reply;
327 
328  reply = alloc_command();
329  if (reply == NULL) {
330  printf("cannot reply.\r\n");
331  return;
332  }
333  command_add_arg(reply, "flags1=%i", config_get_ram_struct()->flags1);
334  command_add_arg(reply, "flags2=%i", config_get_ram_struct()->flags2);
335  command_add_arg(reply, "flags=%N", config_get_flags());
336  reply->flags = COMFLAGS_ACK | COMFLAGS_SUCCESS;
337  reply->index = com->index;
338  reply->target = com->sender;
339  reply->encoding = 'a';
340  reply->connid = com->connid;
341  reply->com = com->com;
342 
343  deliver_command(reply, NULL);
344 }
345 
349 void wifi_info(struct command *com) {
350  struct ipv4address *ip;
351  struct command *reply;
352 
353  ip = esp8266_get_current_ip();
354  reply = alloc_command();
355  if (reply == NULL) {
356  printf("cannot reply.\r\n");
357  return;
358  }
359  command_add_arg(reply, "ws=%i", esp8266_get_firmware_version());
360  if (ip != NULL) {
361  command_add_arg(reply, "ip=%i.%i.%i.%i", ip->ip1, ip->ip2, ip->ip3, ip->ip4);
362  }
363  const char *ssid = esp_get_last_ssid();
364 
365  if (ssid != NULL) {
366  command_add_arg(reply, "ssid=%s", ssid);
367  }
368  const char *pw = esp_get_last_pw();
369 
370  if (pw != NULL) {
371  command_add_arg(reply, "pw=%s", pw);
372  }
373  command_add_arg(reply, "rsctr=%i", get_esp_reboot_ctr());
374  reply->flags = COMFLAGS_ACK | COMFLAGS_SUCCESS;
375  reply->index = com->index;
376  reply->target = com->sender;
377  reply->encoding = 'a';
378  reply->connid = com->connid;
379  reply->com = com->com;
380 
381  deliver_command(reply, NULL);
382 }
383 
387 void getcloudtoken(struct command *com) {
388  struct command *reply;
389 
390  reply = alloc_command();
391  if (reply == NULL) {
392  printf("cannot reply.\r\n");
393  return;
394  }
395  const char *tok = config_get_cloud_token();
396 
397  if (tok != NULL) {
398  command_add_arg(reply, "key=%s", tok);
399  reply->flags = COMFLAGS_ACK | COMFLAGS_SUCCESS;
400  } else {
401  reply->flags = COMFLAGS_ACK;
402  }
403  reply->index = com->index;
404  reply->target = com->sender;
405  reply->encoding = 'a';
406  reply->connid = com->connid;
407  reply->com = com->com;
408 
409  deliver_command(reply, NULL);
410 }
411 
416 void getpubkey(struct command *com) {
417  send_command_reply(com, COMFLAGS_ACK | COMFLAGS_SUCCESS);
418 }
419 
420 static void gpio_set_dac(int dac, int val) {
421  printf("gpio_set_dac not implemented in command-handler.c\r\n");
422 }
423 
424 void setdac(struct command *com) {
425  if (com->argctr == 2) {
426  int dac = atoi(get_arg(com, 0));
427  int val = atoi(get_arg(com, 1));
428  dac_toggle_step = 0;
429  gpio_set_dac(dac, val);
430  } else if (com->argctr == 5) {
431  dac_toggle_high = atoi(get_arg(com, 1));
432  dac_toggle_low = atoi(get_arg(com, 2));
433  dac_toggle_step = atoi(get_arg(com, 3));
434  dac_toggle_speed = atoi(get_arg(com, 4));
435  if (dac_toggle_low > dac_toggle_high) {
436  int x = dac_toggle_low;
437  dac_toggle_low = dac_toggle_high;
438  dac_toggle_high = x;
439  }
440  dac_cur_value = dac_toggle_low;
441  dac_toggle_cur = 0;
442  if (dac_toggle_step == 0) {
443  gpio_set_dac(0, 0);
444  }
445  }
446  send_command_reply(com, COMFLAGS_ACK | COMFLAGS_SUCCESS);
447 }
451 void list_modules(struct command *com) {
452  printf("Listing modules...\r\n");
453  struct command *dcom;
454  int nodes;
455  struct hostroute *host;
456  int i;
457 
458  dcom = alloc_command();
459  if (dcom == NULL) {
460  send_command_reply(com, COMFLAGS_ACK);
461  return;
462  }
463  nodes = routing_count_nodes();
464  printf("Got %i nodes\r\n", nodes);
465  for (i = 0; i < nodes; i++) {
467  if (host != NULL) {
468  printf("%p\r\n", (void *)host->host);
469  command_init(dcom);
470  //dcom->recipient = com->sender; // WRONG!! next hop!
471  dcom->target = com->sender;
472  dcom->encoding = 'a';
473  dcom->index = com->index;
474  dcom->sourcedev = com->sourcedev;
475  dcom->connid = com->connid;
476  dcom->com = com->com;
477  dcom->flags = COMFLAGS_DATA | COMFLAGS_SUCCESS;
478  command_add_arg(dcom, "%N", host->host);
479  command_add_arg(dcom, "%i", host->hosttype);
480  command_add_arg(dcom, "%i", host->device);
481  send_command(dcom);
482  free_command(dcom);
483  }
484  }
485  send_command_reply(com, COMFLAGS_ACK | COMFLAGS_SUCCESS);
486 }
487 
488 static void button_pressed(struct command *com) {
489  // do what here exactly?
490 }
491 static void installed_info(struct command *com) {
492  char buf[100];
493  int max = loader_get_app_base_address_count();
494  int i;
495 
496  for (i = 0; i < max; i++) {
497  struct app_header *app = loader_get_app_base_address(i);
498  if (app == NULL) {
499  continue;
500  }
501  struct meta_header *header = loader_get_app_meta_address(i);
502  int seq = 0;
503  if (header != NULL) {
504  seq = header->meta_seq;
505  }
506  snprintf(buf, 99, "av=%i,ad=%p,ab=%p,repo=%i,seq=%i,idx=%i",
507  app->version,
508  app->buildtime,
509  app,
510  app->repoid,
511  seq,
512  i
513  );
514  printf("INSTALLED: %s\r\n", buf);
515  if (send_data(com, "%s", buf) != 0) {
516  goto fail;
517  }
518  }
519  send_command_reply(com, COMFLAGS_ACK | COMFLAGS_SUCCESS);
520  return;
521 fail:
522  send_command_reply(com, COMFLAGS_ACK);
523 }
524 static void software_info(struct command *com) {
525  struct command *dcom;
526 
527  dcom = get_data_reply(com);
528  if (dcom == NULL) {
529  goto fail;
530  }
531 
532  command_add_arg(dcom, "av=%i", CNW_BUILD_VERSION);
533  command_add_arg(dcom, "ad=%p", CNW_BUILD_TIMESTAMP);
534  command_add_arg(dcom, "ab=%p", get_app_header());
535  command_add_arg(dcom, "repo=%i", get_app_header()->repoid);
536  command_add_arg(dcom, "ws=%i", esp8266_get_firmware_version());
537  command_add_arg(dcom, "ua=%p", config_get_userapp());
538  if (config_get_userapp() != 0) {
539  struct userapp_info *ua = get_user_app();
540  command_add_arg(dcom, "uv=%i", ua->version);
541  command_add_arg(dcom, "ur=%i", ua->repoid);
542  }
543 
544  send_command(dcom);
545  free_command(dcom);
546 
547  dcom = get_data_reply(com);
548  if (dcom == NULL) {
549  goto fail;
550  }
551  command_add_arg(dcom, "lv=%i", loader_get_version());
552  command_add_arg(dcom, "lpc=%p", constants()->last_return_address);
553  command_add_arg(dcom, "fadr=%p", constants()->failing_address);
554  command_add_arg(dcom, "cfsr=%p", constants()->CFSR);
555  command_add_arg(dcom, "curts=%i", mculib_get_seconds_since_boot());
556  command_add_arg(dcom, "rc=%p", loader_get_last_reset_cause());
557  send_command(dcom);
558  free_command(dcom);
559 
560 
561  if (send_command_reply(com, COMFLAGS_ACK | COMFLAGS_SUCCESS)) {
562  goto fail;
563  }
564  printf("sent data for software info\r\n");
565  return;
566 fail:
567  send_command_reply(com, COMFLAGS_ACK);
568  printf("Failed to sent data for software info\r\n");
569 }
570 
571 
572 void dac_timer() {
573  check_strobe();
574  if (dac_toggle_step == 0) {
575  return;
576  }
577  if (dac_toggle_cur < dac_toggle_speed) {
578  dac_toggle_cur++;
579  return;
580  }
581  dac_toggle_cur = 0;
582  if (dac_cur_dir == 0) {
583  dac_cur_value = dac_cur_value + dac_toggle_step;
584  if (dac_cur_value >= dac_toggle_high) {
585  dac_cur_dir = 1;
586  }
587  } else {
588  dac_cur_value = dac_cur_value - dac_toggle_step;
589  if (dac_cur_value <= dac_toggle_low) {
590  dac_cur_dir = 0;
591  }
592  }
593  gpio_set_dac(0, dac_cur_value);
594 }
595 
596 
597 void check_strobe() {
598  if (strobe_timeout_on == 0) {
599  return;
600  }
601  int max = 0;
602 
603  if (strobe_state == 1) {
604  max = strobe_timeout_off;
605  } else {
606  max = strobe_timeout_on;
607  }
608  if (strobe_cur < max) {
609  strobe_cur++;
610  return;
611  }
612  strobe_cur = 1;
613  if (strobe_state == 0) {
614  mculib_pin_set(MAIN_MCULIBHANDLE, strobe_relay, 0);
615  strobe_state = 1;
616  } else {
617  strobe_repeat--;
618  mculib_pin_set(MAIN_MCULIBHANDLE, strobe_relay, 1);
619  strobe_state = 0;
620  }
621  if (strobe_repeat <= 0) {
622  strobe_timeout_on = 0;
623  restore_pin(strobe_relay);
624  }
625 }
626 
627 void start_strobe(int relay, int ton, int toff, int repeat) {
628  int r;
629 
630  if ((r = mculib_pin_out(MAIN_MCULIBHANDLE, relay, HAL_PIN_FASTEST))) {
631  printf("Strobe: failed to set pin %i to out: %i\r\n", relay, r);
632  return;
633  }
634  store_pin(relay);
635  strobe_state = 0;
636  strobe_relay = relay;
637  strobe_timeout_on = ton;
638  strobe_timeout_off = toff;
639  strobe_repeat = repeat;
640  strobe_cur = 1;
641  mculib_pin_set(MAIN_MCULIBHANDLE, strobe_relay, 1);
642 }
643 
644 
645 static void sensorrequest(struct command *com) {
646  int x;
647 
648  if (com->argctr != 3) {
649  printf("Need exactly 3 args for sensorrequest, not %i\r\n", com->argctr);
650  // send fail?
651  return;
652  }
653  const void *sensorname = get_arg(com, 0);
654  long idx = ascii_parse_hex(sensorname, strlen(sensorname), NULL);
655  const void *nodeid = get_arg(com, 1);
656  long h = ascii_parse_hex(nodeid, strlen(nodeid), NULL);
657 
658  printf("nodeid: %s (%p)\r\n", nodeid, h);
659  int paras[3];
660 
661  if ((x = get_arg_int_array(com, 2, (int *)paras, 3)) != 3) {
662  printf("Too few arguments (need 3, got %i\r\n)", x);
663  completion(com, 2);
664  return;
665  }
666 
667  completion(com, sensor_submit_request(h, (int)idx, paras[0], paras[1], paras[2]));
668 }
669 static void blinkled(struct command *com) {
670  if (com->argctr < 3) {
671  printf("Need at least 3 args for blinkled, not %i\r\n", com->argctr);
672  // send fail?
673  return;
674  }
675  led_set_user_managed();
676  int col = atoi(get_arg(com, 0));
677  int on = atoi(get_arg(com, 1));
678  int off = atoi(get_arg(com, 2));
679  int brightness = 256;
680 
681  if (com->argctr > 3) {
682  brightness = atoi(get_arg(com, 3));
683  }
684  uint32_t flags = 0;
685 
686  if (com->argctr > 4) {
687  flags = atoi(get_arg(com, 4));
688  }
689  printf("Led blink in colour %i, brightness=%i, on=%i, off=%i\r\n", col, brightness, on, off);
690  if (col == 0) {
691  led_off(LED_USER);
692  led_set_machine_managed();
693  } else {
694  led_blink_flags(LED_USER, col, brightness, on, off, flags);
695  }
696  send_command_reply(com, COMFLAGS_ACK | COMFLAGS_SUCCESS);
697  led_print_status();
698 }
699 void process_strobe_command(struct command *com) {
700  if (com->argctr != 4) {
701  return;
702  }
703 
704  start_strobe(atoi(get_arg(com, 0)), atoi(get_arg(com, 1)), atoi(get_arg(com, 2)), atoi(get_arg(com, 3)));
705 }
706 
707 
708 
716 void process_command(struct command *com) {
717  int i;
718 
719  if (!is_packet_for_us(com)) {
720  return;
721  }
722  if (com->flags & COMFLAGS_ACK) {
723  // do not send this via log! - log will be ack'ed
724  printf("ack received for %i (com=%i)\r\n", com->index, com->com);
725  // packet is an ack
726  i = process_queue_reply(com);
727  if (i > 0) {
728  IPLOG("ack processed for %i (com=%i)\r\n", com->index, com->com);
729  return;
730  }
731  if (i == 0) {
732  // we received a reply, but we (no longer) know which command triggered it!
733  printf("ack received for %i (com=%i), but no trigger command found?\r\n", com->index, com->com);
734  if (com->com == 12) {
735  routing_request_reply(com); // update routing table
736  }
737  }
738  if (i < 0) {
739  printf("ack received for %i (com=%i), but failed to process it.\r\n", com->index, com->com);
740  }
741  return;
742  }
743  if (com->flags & COMFLAGS_DATA) {
744  printf("data received for %i (com=%i)\r\n", com->index, com->com);
745  // packet is data
746  return;
747  }
748 
749 
750  if (com->com != 28) {
751  // skip printing streamdata - too many!
752  IPLOG("Processing incoming command.:\r\n");
753  command_print(com);
754  }
755 
756  /****************************************************
757  * some commands will be executed prior to userhook
758  * to ensure we can recover from broken userhooks
759  ****************************************************/
760 
761  if (com->com == 6) {
762  if (com->argctr == 0) {
763  reboot_hard();
764  } else {
765  reboot(atoi(get_arg(com, 0)));
766  }
767  } else if (com->com == 23) {
768  // routing update
769  send_routing_update_now();
770  } else if (com->com == 24) {
771  // factory default
772  factory_default(com);
773  } else if (com->com == 25) {
774  software_info(com); // software info
775  } else if (com->com == 26) {
776  // button pressed
777  button_pressed(com);
778  } else if (com->com == 27) {
779  streamsetup(com);
780  } else if (com->com == 28) {
781  streamdata(com);
782  } else if (com->com == 19) {
783  flashcom(com);
784  } else if (com->com == 36) {
785  installed_info(com);
786  } else if (com->com == 35) {
787  // start app is super important - perhaps we fuck up flashing?
788  restart_app_idx(atoi(get_arg(com, 0)));
789  }
790 
791 
792  /****************************************************
793  * now we call the userhook and may or may not
794  * continue normal processing, depending on return value
795  ****************************************************/
796 
797  // we call the userhook
798  if (user_app_executable()) {
799  completion(com, invoke_on_command_received(com));
800  }
801 
802  /****************************************************
803  * normal processing of commands
804  * (unless command is superimportant - implement here)
805  ****************************************************/
806 
807  if (com->com == 1) {
808  send_command_reply(com, COMFLAGS_ACK | COMFLAGS_SUCCESS);
809  } else if (com->com == 4) { // set-wireless
810  esp8266_add_ap(get_arg(com, 0), get_arg(com, 1));
811  } else if (com->com == 5) {
812  setpin(com);
813  } else if (com->com == 7) {
814  esp8266_reset();
815  } else if (com->com == 8) { // radio-ping
816  //
817  } else if (com->com == 9) { // radiopingloop
818  //
819  } else if (com->com == 10) {
820  printf("Freezing...\r\n");
821  for (;;) {
822  ; // I am frozen ;)
823  }
824  } else if (com->com == 11) {
825  list_modules(com);
826  } else if (com->com == 13) {
827  process_strobe_command(com);
828  } else if (com->com == 14) {
829  getpubkey(com);
830  } else if (com->com == 15) {
831  setcloudtoken(com);
832  } else if (com->com == 16) {
833  set_logging(com);
834  send_command_reply(com, COMFLAGS_ACK);
835  } else if (com->com == 17) {
836  setdac(com);
837  } else if (com->com == 18) {
838  printf("Set serial port not implemented\r\n");
839  } else if (com->com == 20) {
840  micro_strobe(com);
841  } else if (com->com == 30) {
842  blinkled(com);
843  } else if (com->com == 31) {
844  sensorrequest(com);
845  } else if (com->com == 33) {
846  completion(com, received_radio_get_config(com));
847  } else if (com->com == 34) {
848  completion(com, received_radio_set_config(com));
849  } else if (com->com == 21) {
850  set_server_name(com);
851  } else if (com->com == 38) {
852  getcloudtoken(com);
853  } else if (com->com == 39) {
854  forward_radio(com);
855  } else if (com->com == 41) {
856  set_config_flag(com);
857  } else if (com->com == 43) {
858  set_sensor_server_name(com);
859  } else if (com->com == 44) {
860  wifi_info(com);
861  } else if (com->com == 45) {
862  get_config_flags(com);
863  } else if (com->com == 46) {
864  esp8266_wifi_scan(com);
865  } else if (com->com == 47) {
866  route_command(com);
867  } else if (com->com == 48) {
868  sensor_com_list(com);
869  } else if (com->com == 49) {
870  sensor_com_config(com);
871  } else if (com->com == 52) {
872  set_config(com);
873  } else if (com->com == 53) {
874  user_app_info(com);
875  } else if (com->com == 54) {
876  user_app_control(com);
877  } else if (com->com == 57) {
878  completion(com, esp32_bt_trigger_read_characteristic_com(com));
879  } else if (com->com == 55) {
880  completion(com, esp32_bt_set_characteristic_com(com));
881  } else if (com->com == 58) {
882  completion(com, esp32_bt_peers(com));
883  } else if (com->com == 59) {
884  completion(com, time_command_received(com)); // clock-sync
885  }
886 
887 
888  if ((com->com == 3)
889  || (com->com == 4)
890  || (com->com == 8)
891  || (com->com == 9)
892  || (com->com == 10)
893  || (com->com == 13)
894  || (com->com == 5)) {
895  send_command_reply(com, COMFLAGS_ACK | COMFLAGS_SUCCESS);
896  }
897 
898  free_command(com);
899 }
900 
901 // command 52 "setconfig"
902 static void set_config(struct command *com) {
903  const char *na = namedarg(com, "modid");
904 
905  if (na != NULL) {
906  uint64_t modid = atoi(na);
907  config_set_moduleid(modid);
908  }
909  send_command_reply(com, COMFLAGS_ACK | COMFLAGS_SUCCESS);
910 }
911 
912 /***************************** store/restore pin status *******************************/
913 // for after strobe..
914 static void store_pin(int pin) {
915  int i = 0;
916  int r;
917  int t = 0;
918 
919  r = mculib_pin_get(MAIN_MCULIBHANDLE, pin);
920  if (r == 0) {
921  // noop
922  } else if (r == 1) {
923  t = (1 << 9);
924  } else {
925  printf("failed to get pin state: %i\r\n", r);
926  return;
927  }
928  for (i = 0; i < MAX_PIN_STATES; i++) {
929  if (((pinstates[i] & 0xFF) == pin) && (pinstates[i] & (1 << 8))) {
930  // do not overwrite value
931  return;
932  }
933  if ((pinstates[i] & (1 << 8)) && ((pinstates[i] & 0xFF) != pin)) {
934  continue;
935  }
936  pinstates[i] = (uint16_t)(((uint8_t)pin) | (1 << 8)) | t;
937  printf("Stored pin %i: %i\r\n", pin, (int)pinstates[i]);
938  return;
939  }
940  printf("Unable to store pin %i: out of free slots\r\n", pin);
941 }
942 
943 // runs in IRQ!
944 static void restore_pin(int pin) {
945  int i = 0;
946  int r;
947  uint16_t p;
948 
949  for (i = 0; i < MAX_PIN_STATES; i++) {
950  p = pinstates[i];
951  if ((p & (1 << 8)) == 0) {
952  continue;
953  }
954  if ((p & 0xFF) != pin) {
955  continue;
956  }
957  r = 0;
958  if (p & (1 << 9)) {
959  r = 1;
960  }
961  mculib_pin_set(MAIN_MCULIBHANDLE, pin, r);
962  pinstates[i] = 0;
963  break;
964  }
965 }
definitions of routing table structures
void getcloudtoken(struct command *com)
get the opaque cloud token
int is_packet_for_us(struct command *com)
check if a command needs to be routed
int process_queue_reply(struct command *com)
process a reply
Definition: queue.c:324
void logging_set_node(long nodeid)
log to a given node. Usually this would be an app or a server
Definition: logging.c:27
void list_modules(struct command *com)
we received a list-modules command
void streamdata(struct command *com)
called when we receive a stream data packet TODO: this is a really simplistic, memory-consumption opt...
Definition: streams.c:422
int received_radio_set_config(struct command *com)
called when we received radio_set_config command modified the current radio config
Definition: ti1101.c:905
void getpubkey(struct command *com)
request the public key of this module
void set_config_flag(struct command *com)
set a single config flag
void logging_off()
disable logging and logging processing. guarantees that no buffers are used for logging
Definition: logging.c:34
int send_command(struct command *com)
send a command to another module (or broadcast)
Definition: queue.c:372
void free_command(struct command *com)
free a command
Definition: queue.c:198
int deliver_command(struct command *com, pkt_callback)
deliver a command to a module
Definition: queue.c:649
struct command * get_data_reply(struct command *com)
allocates and initializes a packet to be send as "data" to the command typically you'd add some data ...
Definition: queue.c:269
void ti1101_forward_radio(long node)
forward all radio packets to this node mostly useful to debug and decode and sniff 3rd party protocol...
Definition: ti1101.c:928
struct command * alloc_command()
allocate a free command
Definition: queue.c:171
void factory_default(struct command *com)
set the module back to factory default
void command_add_arg(struct command *com, const char *format,...)
adds an arg to a partially initialised command structure
void streamsetup(struct command *com)
called when we receive a stream setup packet
Definition: streams.c:276
long get_my_node_id()
get the id of my node
long host
Definition: routing.h:21
struct hostroute * routing_get_node_by_index(const int index)
finds a nodeid by index. [0...n]
Definition: routing.c:219
int received_radio_get_config(struct command *com)
called when we received radio_get_config command sends back an answer with the current radio config
Definition: ti1101.c:860
void micro_strobe(struct command *com)
do a nano strobe
void esp8266_reset()
reset state machine and esp8266
Definition: esp8266.c:376
int send_command_reply(struct command *com, byte flags)
send a reply to a command
Definition: queue.c:560
int routing_count_nodes()
determine number of nodes known
Definition: routing.c:203
void command_init(struct command *com)
initialize a command structure with default values
int ack_ctr
void process_command(struct command *com)
command is parsed, now execute it
struct ipv4address * esp8266_get_current_ip()
return last ip (null if none)
Definition: esp8266.c:1164
void logging_on()
enable logging and logging processing. buffers are used for logging
Definition: logging.c:42
int get_arg_int_array(const struct command *com, const int index, int *result, const int arraysize)
given a command and argument index, will attempt to parse the arg as array and return it array syntax...
const char * namedarg(struct command *com, const char *name)
get a named arg (key-value pair) or NULL
void get_config_flags(struct command *com)
get config flags
int send_data(struct command *com, const char *format,...)
send the format string as data in response to command "com"
Definition: queue.c:292
void command_print(struct command *com)
prints a command in human readable format to serial console
void flashcom(struct command *com)
set up a flash connection, associate with stream, called by command-handler for command "flash-app"
Definition: flashapp.c:220
void esp_init()
call this ONCE before calling anything else
Definition: esp8266.c:865
void wifi_info(struct command *com)
get some information about our currentwifi connection
const char * get_arg(const struct command *com, int index)
given an argument by index[0..n], will return a pointer to the bytearray (excluding the fieldtype) th...
void setcloudtoken(struct command *com)
set a token to connect to the cloud
int forward_packet(struct command *com)
a command is forwarded to target based on our hostroutes
Definition: forwarding.c:31
void esp8266_add_ap(const char *ssid, const char *pw)
add an ap to the list of known ap
Definition: esp8266.c:413
void init_command_handler()
resets the command handler
void esp8266_send_instructions()
send our nodeid and other goodies to the esp8266 chip
Definition: esp8266.c:1246
void routing_request_reply(const struct command *com)
we call this when we receive a reply to a routing request this adds or updates a new route
Definition: routing.c:359
definitions of routing table structures
int com
Definition: command.h:22
long target
Definition: command.h:16
uint8_t connid
Definition: command.h:18
uint8_t sourcedev
Definition: command.h:17
uint8_t encoding
Definition: command.h:11
long recipient
Definition: command.h:15
int index
Definition: command.h:13
uint8_t flags
Definition: command.h:23
uint8_t argctr
Definition: command.h:24
long sender
Definition: command.h:14
this must be implemented by the userapp, stored in flash at the beginning of the file (offset 0)
user application interface