1 #include <main-header.h>
2 #include <loader-api.h>
3 #include <user_app_exe.h>
5 #include <function-instr.h>
12 #include <sensors/sensor.h>
13 #include <sensors/sensor_command.h>
15 #include <route_command.h>
19 #include "user_app_exe.h"
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;
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];
58 static void restore_pin(
int pin);
59 static void store_pin(
int pin);
61 void process_strobe_command(
struct command *com);
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));
79 void setpin(
struct command *com) {
81 int pin = atoi(
get_arg(com, 0));
82 int state = atoi(
get_arg(com, 1));
84 if ((pin == 100) || (pin == 101)) {
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);
93 r = mculib_pin_set(MAIN_MCULIBHANDLE, pin, state);
95 printf(
"set-pin: failed to set pin: %i\r\n", r);
101 static void completion(
struct command *com,
int result) {
105 }
else if (result == 2) {
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);
131 printf(
"Dropping packet: Invalid recipient ID: %s\r\n", othernode);
134 if (!adr_isvalid(com->
target)) {
135 node_to_str(com->
target, othernode);
136 printf(
"Dropping packet: Invalid target ID: %s\r\n", othernode);
142 || (com->
target == 0xFFFFFFFF)
151 printf(
"comhandler: Forwarding packet to %s...\r\n", othernode);
154 printf(
"forward result: %i\r\n", i);
158 void set_logging(
struct command *com) {
164 enable = atoi(
get_arg(com, 0));
167 long node = ascii_parse_hex((
const byte *)
get_arg(com, 1), 8, &newpos);
169 config_set_log_node(node);
171 IPLOG(
"logging enabled\r\n");
176 IPLOG(
"Disabling logging\r\n");
178 config_set_log_node(0);
182 void static inline xdelay_us(
int us,
int timeout) {
184 int x = us * timeout;
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));
205 for (i = 0; i < repeat; i++) {
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);
217 printf(
"Did strobe timeout_on=%i,timeout_off=%i...\r\n", timeout_on, timeout_off);
223 printf(
"Erasing config...\r\n");
225 loader_erase_config();
226 printf(
"Rebooting...\r\n");
238 long res = config_get_ram_struct()->nodeid;
240 if (!adr_isvalid(res)) {
243 res = res & 0xFFFFFFFF;
255 printf(
"Missing cloud token!\r\n");
259 const char *token =
get_arg(com, 0);
262 printf(
"cloud token must not be NULL!\r\n");
266 printf(
"Setting a cloud token\r\n");
267 config_set_cloud_token(token);
273 void forward_radio(
struct command *com) {
275 long node = ascii_parse_hex((
const byte *)
get_arg(com, 0), 8, &newpos);
283 static void set_server_name(
struct command *com) {
284 config_set_cloud_server(
get_arg(com, 0));
287 printf(
"Command-handler: set new cloud server to %s\r\n",
get_arg(com, 0));
293 static void set_sensor_server_name(
struct command *com) {
295 IPLOG(
"Error - need exactly 2 arguments to set_server_name, not %i\r\n", com->
argctr);
299 const char *srv =
get_arg(com, 0);
301 printf(
"Setting sensor server to \"%s\"\r\n", srv);
302 config_set_sensor_server(srv);
311 IPLOG(
"Error - need exactly 2 arguments to set_config_flag, not %i\r\n", com->
argctr);
315 int flag = atoi(
get_arg(com, 0));
316 int value = atoi(
get_arg(com, 1));
318 config_set_flag(flag, value);
330 printf(
"cannot reply.\r\n");
336 reply->
flags = COMFLAGS_ACK | COMFLAGS_SUCCESS;
356 printf(
"cannot reply.\r\n");
361 command_add_arg(reply,
"ip=%i.%i.%i.%i", ip->ip1, ip->ip2, ip->ip3, ip->ip4);
363 const char *ssid = esp_get_last_ssid();
368 const char *pw = esp_get_last_pw();
374 reply->
flags = COMFLAGS_ACK | COMFLAGS_SUCCESS;
392 printf(
"cannot reply.\r\n");
395 const char *tok = config_get_cloud_token();
399 reply->
flags = COMFLAGS_ACK | COMFLAGS_SUCCESS;
401 reply->
flags = COMFLAGS_ACK;
420 static void gpio_set_dac(
int dac,
int val) {
421 printf(
"gpio_set_dac not implemented in command-handler.c\r\n");
425 if (
com->argctr == 2) {
429 gpio_set_dac(dac, val);
430 }
else if (
com->argctr == 5) {
435 if (dac_toggle_low > dac_toggle_high) {
436 int x = dac_toggle_low;
437 dac_toggle_low = dac_toggle_high;
440 dac_cur_value = dac_toggle_low;
442 if (dac_toggle_step == 0) {
452 printf(
"Listing modules...\r\n");
464 printf(
"Got %i nodes\r\n", nodes);
465 for (i = 0; i < nodes; i++) {
468 printf(
"%p\r\n", (
void *)
host->host);
477 dcom->
flags = COMFLAGS_DATA | COMFLAGS_SUCCESS;
488 static void button_pressed(
struct command *com) {
491 static void installed_info(
struct command *com) {
493 int max = loader_get_app_base_address_count();
496 for (i = 0; i < max; i++) {
497 struct app_header *app = loader_get_app_base_address(i);
501 struct meta_header *header = loader_get_app_meta_address(i);
503 if (header != NULL) {
504 seq = header->meta_seq;
506 snprintf(buf, 99,
"av=%i,ad=%p,ab=%p,repo=%i,seq=%i,idx=%i",
514 printf(
"INSTALLED: %s\r\n", buf);
524 static void software_info(
struct command *com) {
538 if (config_get_userapp() != 0) {
564 printf(
"sent data for software info\r\n");
568 printf(
"Failed to sent data for software info\r\n");
574 if (dac_toggle_step == 0) {
577 if (dac_toggle_cur < dac_toggle_speed) {
582 if (dac_cur_dir == 0) {
583 dac_cur_value = dac_cur_value + dac_toggle_step;
584 if (dac_cur_value >= dac_toggle_high) {
588 dac_cur_value = dac_cur_value - dac_toggle_step;
589 if (dac_cur_value <= dac_toggle_low) {
593 gpio_set_dac(0, dac_cur_value);
597 void check_strobe() {
598 if (strobe_timeout_on == 0) {
603 if (strobe_state == 1) {
604 max = strobe_timeout_off;
606 max = strobe_timeout_on;
608 if (strobe_cur < max) {
613 if (strobe_state == 0) {
614 mculib_pin_set(MAIN_MCULIBHANDLE, strobe_relay, 0);
618 mculib_pin_set(MAIN_MCULIBHANDLE, strobe_relay, 1);
621 if (strobe_repeat <= 0) {
622 strobe_timeout_on = 0;
623 restore_pin(strobe_relay);
627 void start_strobe(
int relay,
int ton,
int toff,
int repeat) {
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);
636 strobe_relay = relay;
637 strobe_timeout_on = ton;
638 strobe_timeout_off = toff;
639 strobe_repeat = repeat;
641 mculib_pin_set(MAIN_MCULIBHANDLE, strobe_relay, 1);
645 static void sensorrequest(
struct command *com) {
649 printf(
"Need exactly 3 args for sensorrequest, not %i\r\n", com->
argctr);
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);
658 printf(
"nodeid: %s (%p)\r\n", nodeid, h);
662 printf(
"Too few arguments (need 3, got %i\r\n)", x);
667 completion(com, sensor_submit_request(h, (
int)idx, paras[0], paras[1], paras[2]));
669 static void blinkled(
struct command *com) {
671 printf(
"Need at least 3 args for blinkled, not %i\r\n", com->
argctr);
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;
682 brightness = atoi(
get_arg(com, 3));
689 printf(
"Led blink in colour %i, brightness=%i, on=%i, off=%i\r\n", col, brightness, on, off);
692 led_set_machine_managed();
694 led_blink_flags(LED_USER, col, brightness, on, off, flags);
699 void process_strobe_command(
struct command *com) {
722 if (com->
flags & COMFLAGS_ACK) {
724 printf(
"ack received for %i (com=%i)\r\n", com->
index, com->
com);
728 IPLOG(
"ack processed for %i (com=%i)\r\n", com->
index, com->
com);
733 printf(
"ack received for %i (com=%i), but no trigger command found?\r\n", com->
index, com->
com);
734 if (com->
com == 12) {
739 printf(
"ack received for %i (com=%i), but failed to process it.\r\n", com->
index, com->
com);
743 if (com->
flags & COMFLAGS_DATA) {
744 printf(
"data received for %i (com=%i)\r\n", com->
index, com->
com);
750 if (com->
com != 28) {
752 IPLOG(
"Processing incoming command.:\r\n");
767 }
else if (com->
com == 23) {
769 send_routing_update_now();
770 }
else if (com->
com == 24) {
773 }
else if (com->
com == 25) {
775 }
else if (com->
com == 26) {
778 }
else if (com->
com == 27) {
780 }
else if (com->
com == 28) {
782 }
else if (com->
com == 19) {
784 }
else if (com->
com == 36) {
786 }
else if (com->
com == 35) {
788 restart_app_idx(atoi(
get_arg(com, 0)));
798 if (user_app_executable()) {
799 completion(com, invoke_on_command_received(com));
809 }
else if (com->
com == 4) {
811 }
else if (com->
com == 5) {
813 }
else if (com->
com == 7) {
815 }
else if (com->
com == 8) {
817 }
else if (com->
com == 9) {
819 }
else if (com->
com == 10) {
820 printf(
"Freezing...\r\n");
824 }
else if (com->
com == 11) {
826 }
else if (com->
com == 13) {
827 process_strobe_command(com);
828 }
else if (com->
com == 14) {
830 }
else if (com->
com == 15) {
832 }
else if (com->
com == 16) {
835 }
else if (com->
com == 17) {
837 }
else if (com->
com == 18) {
838 printf(
"Set serial port not implemented\r\n");
839 }
else if (com->
com == 20) {
841 }
else if (com->
com == 30) {
843 }
else if (com->
com == 31) {
845 }
else if (com->
com == 33) {
847 }
else if (com->
com == 34) {
849 }
else if (com->
com == 21) {
850 set_server_name(com);
851 }
else if (com->
com == 38) {
853 }
else if (com->
com == 39) {
855 }
else if (com->
com == 41) {
857 }
else if (com->
com == 43) {
858 set_sensor_server_name(com);
859 }
else if (com->
com == 44) {
861 }
else if (com->
com == 45) {
863 }
else if (com->
com == 46) {
864 esp8266_wifi_scan(com);
865 }
else if (com->
com == 47) {
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) {
873 }
else if (com->
com == 53) {
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));
894 || (com->
com == 5)) {
902 static void set_config(
struct command *com) {
903 const char *na =
namedarg(com,
"modid");
906 uint64_t modid = atoi(na);
907 config_set_moduleid(modid);
914 static void store_pin(
int pin) {
919 r = mculib_pin_get(MAIN_MCULIBHANDLE, pin);
925 printf(
"failed to get pin state: %i\r\n", r);
928 for (i = 0; i < MAX_PIN_STATES; i++) {
929 if (((pinstates[i] & 0xFF) == pin) && (pinstates[i] & (1 << 8))) {
933 if ((pinstates[i] & (1 << 8)) && ((pinstates[i] & 0xFF) != pin)) {
936 pinstates[i] = (uint16_t)(((uint8_t)pin) | (1 << 8)) | t;
937 printf(
"Stored pin %i: %i\r\n", pin, (
int)pinstates[i]);
940 printf(
"Unable to store pin %i: out of free slots\r\n", pin);
944 static void restore_pin(
int pin) {
949 for (i = 0; i < MAX_PIN_STATES; i++) {
951 if ((p & (1 << 8)) == 0) {
954 if ((p & 0xFF) != pin) {
961 mculib_pin_set(MAIN_MCULIBHANDLE, pin, r);
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
void logging_set_node(long nodeid)
log to a given node. Usually this would be an app or a server
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...
int received_radio_set_config(struct command *com)
called when we received radio_set_config command modified the current radio config
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
int send_command(struct command *com)
send a command to another module (or broadcast)
void free_command(struct command *com)
free a command
int deliver_command(struct command *com, pkt_callback)
deliver a command to a module
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 ...
void ti1101_forward_radio(long node)
forward all radio packets to this node mostly useful to debug and decode and sniff 3rd party protocol...
struct command * alloc_command()
allocate a free command
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
long get_my_node_id()
get the id of my node
struct hostroute * routing_get_node_by_index(const int index)
finds a nodeid by index. [0...n]
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
void micro_strobe(struct command *com)
do a nano strobe
void esp8266_reset()
reset state machine and esp8266
int send_command_reply(struct command *com, byte flags)
send a reply to a command
int routing_count_nodes()
determine number of nodes known
void command_init(struct command *com)
initialize a command structure with default values
void process_command(struct command *com)
command is parsed, now execute it
struct ipv4address * esp8266_get_current_ip()
return last ip (null if none)
void logging_on()
enable logging and logging processing. buffers are used for logging
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"
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"
void esp_init()
call this ONCE before calling anything else
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
void esp8266_add_ap(const char *ssid, const char *pw)
add an ap to the list of known ap
void init_command_handler()
resets the command handler
void esp8266_send_instructions()
send our nodeid and other goodies to the esp8266 chip
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
definitions of routing table structures
this must be implemented by the userapp, stored in flash at the beginning of the file (offset 0)
user application interface