1#include <main-header.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"
23static int dac_toggle_high = 0;
24static int dac_toggle_low = 0;
25static int dac_toggle_speed;
26static int dac_toggle_cur;
27static int dac_cur_value = 0;
28static int dac_toggle_step = 0;
29static byte dac_cur_dir = 0;
31static int strobe_relay = 0;
32static int strobe_cur = 0;
33static int strobe_repeat = 0;
34static int strobe_timeout_on = 0;
35static int strobe_timeout_off = 0;
36static int strobe_state = 0;
37#define MAX_PIN_STATES 5
38static uint16_t pinstates[MAX_PIN_STATES];
59static void restore_pin(
int pin);
60static void store_pin(
int pin);
62void process_strobe_command(
struct command *com);
64void start_strobe(
int relay,
int ton,
int toff,
int repeat);
65static void software_info(
struct command *com);
66static void installed_info(
struct command *com);
67static void button_pressed(
struct command *com);
68static void set_server_name(
struct command *com);
69static void set_sensor_server_name(
struct command *com);
70static void set_config(
struct command *com);
71static void powerinfo_command_received(
struct command *com);
79 memset(&pinstates, 0,
sizeof(pinstates));
81void setpin(
struct command *com) {
83 int pin = atoi(
get_arg(com, 0));
84 int state = atoi(
get_arg(com, 1));
86 if ((pin == 100) || (pin == 101)) {
90 printf(
"setting pin %i to %i\r\n", pin, state);
91 if ((r = mculib_pin_out(MAIN_MCULIBHANDLE, pin, HAL_PIN_FASTEST))) {
92 printf(
"set-pin: failed to set pin %i to out: %i\r\n", pin, r);
95 r = mculib_pin_set(MAIN_MCULIBHANDLE, pin, state);
97 printf(
"set-pin: failed to set pin: %i\r\n", r);
103static int completion(
struct command *com,
int result) {
106 }
else if (result == 2) {
124 node_to_str(config_get_ram_struct()->nodeid, ownnode);
125 if (!adr_isvalid(com->
sender)) {
126 node_to_str(com->
sender, othernode);
127 printf(
"Dropping packet: Invalid sender ID: %s\r\n", othernode);
132 printf(
"Dropping packet: Invalid recipient ID: %s\r\n", othernode);
135 if (!adr_isvalid(com->
target)) {
136 node_to_str(com->
target, othernode);
137 printf(
"Dropping packet: Invalid target ID: %s\r\n", othernode);
143 || (com->
target == 0xFFFFFFFF)
152 printf(
"comhandler: Forwarding packet to %s...\r\n", othernode);
155 printf(
"forward result: %i\r\n", i);
159void set_logging(
struct command *com) {
165 enable = atoi(
get_arg(com, 0));
168 long node = ascii_parse_hex((
const byte *)
get_arg(com, 1), 8, &newpos);
170 config_set_log_node(node);
172 IPLOG(
"logging enabled\r\n");
177 IPLOG(
"Disabling logging\r\n");
179 config_set_log_node(0);
183void static inline xdelay_us(
int us,
int timeout) {
185 int x = us * timeout;
198 int pin = atoi(
get_arg(com, 0));
199 int timeout_on = atoi(
get_arg(com, 1));
200 int timeout_off = atoi(
get_arg(com, 2));
201 int repeat = atoi(
get_arg(com, 3));
202 int us = atoi(
get_arg(com, 4));
206 for (i = 0; i < repeat; i++) {
212 mculib_pin_set(MAIN_MCULIBHANDLE, pin, 1);
213 xdelay_us(us, timeout_on);
214 mculib_pin_set(MAIN_MCULIBHANDLE, pin, 0);
215 xdelay_us(us, timeout_off);
218 printf(
"Did strobe timeout_on=%i,timeout_off=%i...\r\n", timeout_on, timeout_off);
224 printf(
"Erasing config...\r\n");
226 loader_erase_config();
227 printf(
"Rebooting...\r\n");
239 long res = config_get_ram_struct()->nodeid;
241 if (!adr_isvalid(res)) {
244 res = res & 0xFFFFFFFF;
256 printf(
"Missing cloud token!\r\n");
260 const char *token =
get_arg(com, 0);
263 printf(
"cloud token must not be NULL!\r\n");
267 printf(
"Setting a cloud token\r\n");
268 config_set_cloud_token(token);
274void forward_radio(
struct command *com) {
276 long node = ascii_parse_hex((
const byte *)
get_arg(com, 0), 8, &newpos);
284static void set_server_name(
struct command *com) {
285 config_set_cloud_server(
get_arg(com, 0));
288 printf(
"Command-handler: set new cloud server to %s\r\n",
get_arg(com, 0));
294static void set_sensor_server_name(
struct command *com) {
296 IPLOG(
"Error - need exactly 2 arguments to set_server_name, not %i\r\n", com->
argctr);
300 const char *srv =
get_arg(com, 0);
302 printf(
"Setting sensor server to \"%s\"\r\n", srv);
303 config_set_sensor_server(srv);
312 IPLOG(
"Error - need exactly 2 arguments to set_config_flag, not %i\r\n", com->
argctr);
316 int flag = atoi(
get_arg(com, 0));
317 int value = atoi(
get_arg(com, 1));
319 config_set_flag(flag, value);
331 printf(
"cannot reply.\r\n");
337 reply->
flags = COMFLAGS_ACK | COMFLAGS_SUCCESS;
357 printf(
"cannot reply.\r\n");
362 command_add_arg(reply,
"ip=%i.%i.%i.%i", ip->ip1, ip->ip2, ip->ip3, ip->ip4);
364 const char *ssid = esp_get_last_ssid();
369 const char *pw = esp_get_last_pw();
375 reply->
flags = COMFLAGS_ACK | COMFLAGS_SUCCESS;
393 printf(
"cannot reply.\r\n");
396 const char *tok = config_get_cloud_token();
400 reply->
flags = COMFLAGS_ACK | COMFLAGS_SUCCESS;
402 reply->
flags = COMFLAGS_ACK;
421static void gpio_set_dac(
int dac,
int val) {
422 printf(
"gpio_set_dac not implemented in command-handler.c\r\n");
426 if (
com->argctr == 2) {
430 gpio_set_dac(dac, val);
431 }
else if (
com->argctr == 5) {
436 if (dac_toggle_low > dac_toggle_high) {
437 int x = dac_toggle_low;
438 dac_toggle_low = dac_toggle_high;
441 dac_cur_value = dac_toggle_low;
443 if (dac_toggle_step == 0) {
453 printf(
"Listing modules...\r\n");
465 printf(
"Got %i nodes\r\n", nodes);
466 for (i = 0; i < nodes; i++) {
469 printf(
"%p\r\n", (
void *)
host->host);
478 dcom->
flags = COMFLAGS_DATA | COMFLAGS_SUCCESS;
489static void button_pressed(
struct command *com) {
493static uint8_t installed_info_to_flags(
int active,
int valid) {
505static void installed_info(
struct command *com) {
506 int version = atoi(
get_arg(com, 0));
508 printf(
"getting installed info Version #%i\r\n", version);
511 int max = loader_get_app_base_address_count();
514 for (i = 0; i < max; i++) {
515 struct app_header *app = loader_get_app_base_address(i);
519 struct meta_header *header = loader_get_app_meta_address(i);
521 if (header != NULL) {
522 seq = header->meta_seq;
524 snprintf(buf, 99,
"av=%i,ad=%p,ab=%p,repo=%i,seq=%i,idx=%i",
532 printf(
"INSTALLED: %s\r\n", buf);
539 }
else if ( (version == 1) || (version == 2)){
545 int max = loader_get_app_base_address_count();
554 buf[1] = max + extra;
558 add_uint16(buf, 100, &offset, 3);
559 add_uint32(buf, 100, &offset, ua->version);
560 add_uint32(buf, 100, &offset, ua->repoid);
561 add_uint64(buf, 100, &offset, (uint64_t)((uint32_t)ua->base));
562 if (version == 2) add_uint32(buf, 100, &offset, 0);
563 add_uint8(buf, 100, &offset, installed_info_to_flags(user_app_is_enabled(), user_app_is_valid()));
568 if (esp8266_get_chip() == 1) {
569 add_uint16(buf, 100, &offset, 4);
570 }
else if (esp8266_get_chip() == 2) {
571 add_uint16(buf, 100, &offset, 5);
573 add_uint16(buf, 100, &offset, 0);
575 add_uint32(buf, 100, &offset, esp8266_get_firmware_version());
576 add_uint32(buf, 100, &offset, esp8266_get_firmware_repo());
577 add_uint64(buf, 100, &offset, esp8266_get_firmware_base());
578 if (version == 2) add_uint32(buf, 100, &offset,0);
579 add_uint8(buf, 100, &offset, installed_info_to_flags(1, 1));
582 for (i = 0; i < max; i++) {
583 struct app_header *app = loader_get_app_base_address(i);
587 add_uint16(buf, 100, &offset, 1);
588 add_uint32(buf, 100, &offset, app->version);
589 add_uint32(buf, 100, &offset, app->repoid);
590 add_uint64(buf, 100, &offset, (uint64_t)((uint32_t)app));
591 if (version == 2) add_uint32(buf, 100, &offset, app->buildtime);
593 if (get_app_header() == app) {
597 add_uint8(buf, 100, &offset, installed_info_to_flags(active, 1));
616static void software_info(
struct command *
com) {
630 if (config_get_userapp() != 0) {
656 printf(
"sent data for software info\r\n");
660 printf(
"Failed to sent data for software info\r\n");
666 if (dac_toggle_step == 0) {
669 if (dac_toggle_cur < dac_toggle_speed) {
674 if (dac_cur_dir == 0) {
675 dac_cur_value = dac_cur_value + dac_toggle_step;
676 if (dac_cur_value >= dac_toggle_high) {
680 dac_cur_value = dac_cur_value - dac_toggle_step;
681 if (dac_cur_value <= dac_toggle_low) {
685 gpio_set_dac(0, dac_cur_value);
690 if (strobe_timeout_on == 0) {
695 if (strobe_state == 1) {
696 max = strobe_timeout_off;
698 max = strobe_timeout_on;
700 if (strobe_cur < max) {
705 if (strobe_state == 0) {
706 mculib_pin_set(MAIN_MCULIBHANDLE, strobe_relay, 0);
710 mculib_pin_set(MAIN_MCULIBHANDLE, strobe_relay, 1);
713 if (strobe_repeat <= 0) {
714 strobe_timeout_on = 0;
715 restore_pin(strobe_relay);
719void start_strobe(
int relay,
int ton,
int toff,
int repeat) {
722 if ((r = mculib_pin_out(MAIN_MCULIBHANDLE, relay, HAL_PIN_FASTEST))) {
723 printf(
"Strobe: failed to set pin %i to out: %i\r\n", relay, r);
728 strobe_relay = relay;
729 strobe_timeout_on = ton;
730 strobe_timeout_off = toff;
731 strobe_repeat = repeat;
733 mculib_pin_set(MAIN_MCULIBHANDLE, strobe_relay, 1);
737static void sensorrequest(
struct command *com) {
741 printf(
"Need exactly 3 args for sensorrequest, not %i\r\n", com->
argctr);
745 const void *sensorname =
get_arg(com, 0);
746 long idx = ascii_parse_hex(sensorname, strlen(sensorname), NULL);
747 const void *nodeid =
get_arg(com, 1);
748 long h = ascii_parse_hex(nodeid, strlen(nodeid), NULL);
750 printf(
"nodeid: %s (%p)\r\n", nodeid, h);
754 printf(
"Too few arguments (need 3, got %i\r\n)", x);
759 completion(com, sensor_submit_request(h, (
int)idx, paras[0], paras[1], paras[2]));
761static void blinkled(
struct command *com) {
763 printf(
"Need at least 3 args for blinkled, not %i\r\n", com->
argctr);
767 led_set_user_managed();
768 int col = atoi(
get_arg(com, 0));
769 int on = atoi(
get_arg(com, 1));
770 int off = atoi(
get_arg(com, 2));
771 int brightness = 256;
774 brightness = atoi(
get_arg(com, 3));
781 printf(
"Led blink in colour %i, brightness=%i, on=%i, off=%i\r\n", col, brightness, on, off);
784 led_set_machine_managed();
786 led_blink_flags(LED_USER, col, brightness, on, off, flags);
791void process_strobe_command(
struct command *com) {
814 if (com->
flags & COMFLAGS_ACK) {
816 printf(
"ack received for %i (com=%i)\r\n", com->
index, com->
com);
820 IPLOG(
"ack processed for %i (com=%i)\r\n", com->
index, com->
com);
825 printf(
"ack received for %i (com=%i), but no trigger command found?\r\n", com->
index, com->
com);
826 if (com->
com == 12) {
831 printf(
"ack received for %i (com=%i), but failed to process it.\r\n", com->
index, com->
com);
835 if (com->
flags & COMFLAGS_DATA) {
836 printf(
"data received for %i (com=%i)\r\n", com->
index, com->
com);
842 if (com->
com != 28) {
844 IPLOG(
"Processing incoming command.:\r\n");
859 }
else if (com->
com == 23) {
861 send_routing_update_now();
862 }
else if (com->
com == 24) {
865 }
else if (com->
com == 25) {
867 }
else if (com->
com == 26) {
870 }
else if (com->
com == 27) {
872 }
else if (com->
com == 28) {
874 }
else if (com->
com == 19) {
876 }
else if (com->
com == 36) {
878 }
else if (com->
com == 35) {
880 restart_app_adr(atoi(
get_arg(com, 0)));
890 if (user_app_executable()) {
891 if (completion(com, invoke_on_command_received(com)) > 0) {
905 }
else if (com->
com == 4) {
907 }
else if (com->
com == 5) {
909 }
else if (com->
com == 7) {
911 }
else if (com->
com == 8) {
913 }
else if (com->
com == 9) {
915 }
else if (com->
com == 10) {
916 printf(
"Freezing...\r\n");
920 }
else if (com->
com == 11) {
922 }
else if (com->
com == 13) {
923 process_strobe_command(com);
924 }
else if (com->
com == 14) {
926 }
else if (com->
com == 15) {
928 }
else if (com->
com == 16) {
931 }
else if (com->
com == 17) {
933 }
else if (com->
com == 18) {
934 printf(
"Set serial port not implemented\r\n");
935 }
else if (com->
com == 20) {
937 }
else if (com->
com == 30) {
939 }
else if (com->
com == 31) {
941 }
else if (com->
com == 33) {
943 }
else if (com->
com == 34) {
945 }
else if (com->
com == 21) {
946 set_server_name(com);
947 }
else if (com->
com == 38) {
949 }
else if (com->
com == 39) {
951 }
else if (com->
com == 41) {
953 }
else if (com->
com == 43) {
954 set_sensor_server_name(com);
955 }
else if (com->
com == 44) {
957 }
else if (com->
com == 45) {
959 }
else if (com->
com == 46) {
960 esp8266_wifi_scan(com);
961 }
else if (com->
com == 47) {
963 }
else if (com->
com == 48) {
964 sensor_com_list(com);
965 }
else if (com->
com == 49) {
966 sensor_com_config(com);
967 }
else if (com->
com == 52) {
969 }
else if (com->
com == 53) {
971 }
else if (com->
com == 54) {
972 user_app_control(com);
973 }
else if (com->
com == 57) {
974 completion(com, esp32_bt_trigger_read_characteristic_com(com));
975 }
else if (com->
com == 55) {
976 completion(com, esp32_bt_set_characteristic_com(com));
977 }
else if (com->
com == 58) {
978 completion(com, esp32_bt_peers(com));
979 }
else if (com->
com == 59) {
980 completion(com, time_command_received(com));
981 }
else if (com->
com == 60) {
982 powerinfo_command_received(com);
992 || (com->
com == 5)) {
1000static void powerinfo_command_received(
struct command *com) {
1005 if (reply == NULL) {
1006 printf(
"cannot reply.\r\n");
1009 reply->
flags = COMFLAGS_ACK | COMFLAGS_SUCCESS;
1015 struct cnw_config *cfg = config_get_ram_struct();
1018 reply->
flags = COMFLAGS_ACK;
1025 add_uint8(buf, 100, &offset, config_get_flag(CONFIG_FLAGS_POWER_SAVE));
1026 add_uint16(buf, 100, &offset, config_get_wifioff_duration());
1027 add_uint16(buf, 100, &offset, config_get_radiooff_duration());
1028 add_uint32(buf, 100, &offset, config_get_powermode_flags());
1029 add_uint16(buf, 100, &offset, cfg->sleep_duration);
1030 add_uint16(buf, 100, &offset, cfg->nonsleep_duration);
1038static void set_config(
struct command *com) {
1039 const char *na =
namedarg(com,
"modid");
1042 uint64_t modid = atoi(na);
1043 config_set_moduleid(modid);
1049 config_set_flag(CONFIG_FLAGS_POWER_SAVE, 1);
1051 config_set_flag(CONFIG_FLAGS_POWER_SAVE, 0);
1055 config_set_powermode_flags(v);
1060 config_set_wifioff_duration(f);
1063 config_set_radiooff_duration(f);
1065 struct cnw_config *cfg = config_get_ram_struct();
1069 cfg->sleep_duration = f;
1072 cfg->nonsleep_duration = f;
1081static void store_pin(
int pin) {
1086 r = mculib_pin_get(MAIN_MCULIBHANDLE, pin);
1089 }
else if (r == 1) {
1092 printf(
"failed to get pin state: %i\r\n", r);
1095 for (i = 0; i < MAX_PIN_STATES; i++) {
1096 if (((pinstates[i] & 0xFF) == pin) && (pinstates[i] & (1 << 8))) {
1100 if ((pinstates[i] & (1 << 8)) && ((pinstates[i] & 0xFF) != pin)) {
1103 pinstates[i] = (uint16_t)(((uint8_t)pin) | (1 << 8)) | t;
1104 printf(
"Stored pin %i: %i\r\n", pin, (
int)pinstates[i]);
1107 printf(
"Unable to store pin %i: out of free slots\r\n", pin);
1111static void restore_pin(
int pin) {
1116 for (i = 0; i < MAX_PIN_STATES; i++) {
1118 if ((p & (1 << 8)) == 0) {
1121 if ((p & 0xFF) != pin) {
1128 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
int namedarg_uint16(struct command *com, const char *name, uint16_t *value)
get a named arg (key-value pair), parsed as integer. result in "value". if return value == 0 ,...
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
void ti1101_forward_radio(long node)
forward all radio packets to this node mostly useful to debug and decode and sniff 3rd party protocol...
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
const char * namedarg(struct command *com, const char *name)
get a named arg (key-value pair) or NULL
long get_my_node_id()
get the id of my node
int namedarg_uint32(struct command *com, const char *name, uint32_t *value)
get a named arg (key-value pair), parsed as integer. result in "value". if return value == 0 ,...
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
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...
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 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
struct command * alloc_command()
allocate a free command
void wifi_info(struct command *com)
get some information about our currentwifi connection
void setcloudtoken(struct command *com)
set a token to connect to the cloud
struct ipv4address * esp8266_get_current_ip()
return last ip (null if none)
int command_add_binary_arg(struct command *com, const int len, const byte *srcbuf)
adds a binary parameter to command returns 0 if ok otherwise errorcode
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
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 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