diff --git a/SCRIPTING.md b/SCRIPTING.md index eac47aa..072f3a5 100644 --- a/SCRIPTING.md +++ b/SCRIPTING.md @@ -56,7 +56,7 @@ In general, scripts conform to the following BNF: <expr> ::= <val> | <val> <op> <expr> | (<expr>) | not (<expr>) | retained_topic(<expr>) | substr(<expr>,<num>,<num>) | - json_parse (<expr>,<expr>) + csvstr(<expr>,<num>,<char>) | json_parse (<expr>,<expr>) <op> := '=' | '>' | gte | str_ge | str_gte | '+' | '-' | '*' | '|' | div @@ -211,6 +211,11 @@ substr(<expr>,<num>,<num>) ``` Extracts characters from a string. The two constant numbers give the starting position (first is postion 0) and the length. If the starting position is negative (write it with colons as e.g. "-2"), it counts backwards from the end of the string. +``` +csvstr(<expr>,<num>,<char>) +``` +Extracts strings from a CSV-list (correctly a string with a delimiter character). The constant number gives the position (first is postion 1) and the char is the delimiter. Examples: csvstr("one,two,three", 2, ",") is "two", csvstr("system/test/1", 2, "/") is "test" + ``` json_parse (<expr>,<expr>) ``` diff --git a/firmware/0x00000.bin b/firmware/0x00000.bin index 6c15bd2..c050421 100644 Binary files a/firmware/0x00000.bin and b/firmware/0x00000.bin differ diff --git a/firmware/0x10000.bin b/firmware/0x10000.bin index 2f92aaf..0692a08 100644 Binary files a/firmware/0x10000.bin and b/firmware/0x10000.bin differ diff --git a/firmware/sha1sums b/firmware/sha1sums index 690205d..e83aaef 100644 --- a/firmware/sha1sums +++ b/firmware/sha1sums @@ -1,2 +1,2 @@ -2d114ceba82ee7e63b16726534888665fe1d7b22 0x00000.bin -bdb01713a737a6f328b6a5953825758622e9e894 0x10000.bin +65c1e77051ecf1d65eb38017df1096f84b5daa4a 0x00000.bin +a4ce86573e9a5a60ae6665a47d624522e054a0b2 0x10000.bin diff --git a/user/cli.c b/user/cli.c new file mode 100644 index 0000000..d43d3dc --- /dev/null +++ b/user/cli.c @@ -0,0 +1,997 @@ +#include "c_types.h" +#include "mem.h" +#include "ets_sys.h" +#include "osapi.h" +#include "os_type.h" + +#include "global.h" + +static char INVALID_LOCKED[] = "Invalid command. Config locked\r\n"; +static char INVALID_NUMARGS[] = "Invalid number of arguments\r\n"; +static char INVALID_ARG[] = "Invalid argument\r\n"; + +bool ICACHE_FLASH_ATTR printf_topic(topic_entry * topic, void *user_data) { + uint8_t *response = (uint8_t *) user_data; + + os_sprintf(response, "%s: \"%s\" (QoS %d)\r\n", + topic->clientcon != + LOCAL_MQTT_CLIENT ? topic->clientcon->connect_info.client_id : "local", topic->topic, topic->qos); + to_console(response); + return false; +} + +bool ICACHE_FLASH_ATTR printf_retainedtopic(retained_entry * entry, void *user_data) { + uint8_t *response = (uint8_t *) user_data; + + os_sprintf(response, "\"%s\" len: %d (QoS %d)\r\n", entry->topic, entry->data_len, entry->qos); + to_console(response); + return false; +} + +#ifdef ALLOW_SCANNING +void ICACHE_FLASH_ATTR scan_done(void *arg, STATUS status) { + char response[128]; + + if (status == OK) { + struct bss_info *bss_link = (struct bss_info *)arg; + + ringbuf_memcpy_into(console_tx_buffer, "\r", 1); + while (bss_link != NULL) { + os_sprintf(response, "%d,\"%s\",%d,\"" MACSTR "\",%d\r\n", + bss_link->authmode, bss_link->ssid, bss_link->rssi, MAC2STR(bss_link->bssid), bss_link->channel); + to_console(response); + bss_link = bss_link->next.stqe_next; + } + } else { + os_sprintf(response, "scan fail !!!\r\n"); + to_console(response); + } + system_os_post(user_procTaskPrio, SIG_CONSOLE_TX, (ETSParam) console_conn); +} +#endif + +int ICACHE_FLASH_ATTR parse_str_into_tokens(char *str, char **tokens, int max_tokens) +{ +char *p, *q, *end; +int token_count = 0; +bool in_token = false; + + // preprocessing + for (p = q = str; *p != 0; p++) { + if (*(p) == '%' && *(p+1) != 0 && *(p+2) != 0) { + // quoted hex + uint8_t a; + p++; + if (*p <= '9') + a = *p - '0'; + else + a = toupper(*p) - 'A' + 10; + a <<= 4; + p++; + if (*p <= '9') + a += *p - '0'; + else + a += toupper(*p) - 'A' + 10; + *q++ = a; + } else if (*p == '\\' && *(p+1) != 0) { + // next char is quoted - just copy it, skip this one + *q++ = *++p; + } else if (*p == 8) { + // backspace - delete previous char + if (q != str) q--; + } else if (*p <= ' ') { + // mark this as whitespace + *q++ = 0; + } else { + *q++ = *p; + } + } + + end = q; + *q = 0; + + // cut into tokens + for (p = str; p != end; p++) { + if (*p == 0) { + if (in_token) { + in_token = false; + } + } else { + if (!in_token) { + tokens[token_count++] = p; + if (token_count == max_tokens) + return token_count; + in_token = true; + } + } + } + return token_count; +} + +void ICACHE_FLASH_ATTR console_handle_command(struct espconn *pespconn) { +#define MAX_CMD_TOKENS 6 + + char cmd_line[MAX_CON_CMD_SIZE + 1]; + char response[256]; + char *tokens[MAX_CMD_TOKENS]; + + int bytes_count, nTokens; + + bytes_count = ringbuf_bytes_used(console_rx_buffer); + ringbuf_memcpy_from(cmd_line, console_rx_buffer, bytes_count); + + cmd_line[bytes_count] = 0; + response[0] = 0; + + nTokens = parse_str_into_tokens(cmd_line, tokens, MAX_CMD_TOKENS); + + if (nTokens == 0) { + char c = '\n'; + ringbuf_memcpy_into(console_tx_buffer, &c, 1); + goto command_handled_2; + } + + if (strcmp(tokens[0], "help") == 0) { + os_sprintf(response, "show [config|stats|mqtt]\r\nsave\r\nreset [factory]\r\nlock [<password>]\r\nunlock <password>\r\nquit\r\n"); + to_console(response); +#ifdef ALLOW_SCANNING + os_sprintf(response, "scan\r\n"); + to_console(response); +#endif + os_sprintf(response, "set [ssid|password|auto_connect|ap_ssid|ap_password|ap_on|ap_open] <val>\r\n"); + to_console(response); + os_sprintf(response, "set [network|dns|ip|netmask|gw] <val>\r\n"); + to_console(response); + os_sprintf(response, "set [config_port|config_access|bitrate|system_output] <val>\r\n"); + to_console(response); + os_sprintf(response, "set [broker_user|broker_password|broker_access|broker_clients] <val>\r\n"); + to_console(response); + os_sprintf(response, "set [broker_subscriptions|broker_retained_messages|broker_autoretain] <val>\r\n"); + to_console(response); + os_sprintf(response, "delete_retained|save_retained\r\n"); + to_console(response); + os_sprintf(response, "publish [local|remote] <topic> <data> [retained]\r\n"); + to_console(response); +#ifdef SCRIPTED + os_sprintf(response, "script <port>|<url>|delete\r\nshow [script|vars]\r\n"); + to_console(response); +#ifdef GPIO +#ifdef GPIO_PWM + os_sprintf(response, "set pwm_period <val>\r\n"); + to_console(response); +#endif +#endif +#endif +#ifdef NTP + os_sprintf(response, "time\r\nset [ntp_server|ntp_interval|<ntp_timezone> <val>\r\n"); + to_console(response); +#endif +#ifdef MQTT_CLIENT + os_sprintf(response, "set [mqtt_host|mqtt_port|mqtt_ssl|mqtt_user|mqtt_password|mqtt_id] <val>\r\n"); + to_console(response); +#endif + + goto command_handled_2; + } + + if (strcmp(tokens[0], "show") == 0) { + int16_t i; + ip_addr_t i_ip; + + if (nTokens == 1 || (nTokens == 2 && strcmp(tokens[1], "config") == 0)) { + os_sprintf(response, "STA: SSID:%s PW:%s%s\r\n", + config.ssid, + config.locked ? "***" : (char *)config.password, config.auto_connect ? "" : " [AutoConnect:0]"); + to_console(response); + + os_sprintf(response, "AP: SSID:%s PW:%s%s%s IP:%d.%d.%d.%d/24\r\n", + config.ap_ssid, + config.locked ? "***" : (char *)config.ap_password, + config.ap_open ? " [open]" : "", + config.ap_on ? "" : " [disabled]", IP2STR(&config.network_addr)); + to_console(response); + + // if static IP, add it + os_sprintf(response, + config.my_addr.addr ? + "Static IP: %d.%d.%d.%d Netmask: %d.%d.%d.%d Gateway: %d.%d.%d.%d\r\n" + : "", IP2STR(&config.my_addr), IP2STR(&config.my_netmask), IP2STR(&config.my_gw)); + to_console(response); + // if static DNS, add it + os_sprintf(response, config.dns_addr.addr ? "DNS: %d.%d.%d.%d\r\n" : "", IP2STR(&config.dns_addr)); + to_console(response); +#ifdef MDNS + if (config.mdns_mode) { + os_sprintf(response, "mDNS: %s interface\r\n", config.mdns_mode==1 ? "STA": "SoftAP"); + to_console(response); + } +#endif +#ifdef REMOTE_CONFIG + if (config.config_port == 0 || config.config_access == 0) { + os_sprintf(response, "No network console access\r\n"); + } else { + os_sprintf(response, "Network console access on port %d (mode %d)\r\n", config.config_port, config.config_access); + } + to_console(response); +#endif + + os_sprintf(response, "MQTT broker max. subscription: %d\r\nMQTT broker max. retained messages: %d%s\r\n", + config.max_subscriptions, config.max_retained_messages, config.auto_retained?" (auto saved)":""); + to_console(response); + + os_sprintf(response, "MQTT broker max. clients: %d\r\n", config.max_clients); + to_console(response); + + if (os_strcmp(config.mqtt_broker_user, "none") != 0) { + os_sprintf(response, + "MQTT broker username: %s\r\nMQTT broker password: %s\r\n", + config.mqtt_broker_user, + config.locked ? "***" : (char *)config.mqtt_broker_password); + to_console(response); + } + response[0] = '\0'; + if (config.mqtt_broker_access == LOCAL_ACCESS) + os_sprintf(response, "MQTT broker: local access only\r\n"); + if (config.mqtt_broker_access == REMOTE_ACCESS) + os_sprintf(response, "MQTT broker: remote access only\r\n"); + if (config.mqtt_broker_access == 0) + os_sprintf(response, "MQTT broker: disabled\r\n"); + to_console(response); +#ifdef MQTT_CLIENT + os_sprintf(response, "MQTT client %s\r\n", mqtt_enabled ? "enabled" : "disabled"); + to_console(response); + + if (os_strcmp(config.mqtt_host, "none") != 0) { + os_sprintf(response, + "MQTT client host: %s\r\nMQTT client port: %d\r\nMQTT client user: %s\r\nMQTT client password: %s\r\nMQTT client id: %s\r\nMQTT SSL: %s\r\n", + config.mqtt_host, config.mqtt_port, config.mqtt_user, + config.locked ? "***" : (char *)config.mqtt_password, config.mqtt_id, + config.mqtt_ssl ? "on" : "off"); + to_console(response); + } +#endif +#ifdef NTP + if (os_strcmp(config.ntp_server, "none") != 0) { + os_sprintf(response, + "NTP server: %s (interval: %d s, tz: %d)\r\n", + config.ntp_server, config.ntp_interval / 1000000, config.ntp_timezone); + to_console(response); + } +#endif + os_sprintf(response, "Clock speed: %d\r\n", config.clock_speed); + to_console(response); + + os_sprintf(response, "Serial bitrate: %d\r\n", config.bit_rate); + to_console(response); + if (!config.system_output) + to_console("System output: off\r\n"); + + goto command_handled_2; + } + + if (nTokens == 2 && strcmp(tokens[1], "stats") == 0) { + uint32_t time = (uint32_t) (get_long_systime() / 1000000); + int16_t i; + + os_sprintf(response, "System uptime: %d:%02d:%02d\r\n", time / 3600, (time % 3600) / 60, time % 60); + to_console(response); + + os_sprintf(response, "Free mem: %d\r\n", system_get_free_heap_size()); + to_console(response); +#ifdef SCRIPTED + os_sprintf(response, "Interpreter loop: %d us\r\n", loop_time); + to_console(response); +#endif + if (connected) { + os_sprintf(response, "External IP-address: " IPSTR "\r\n", IP2STR(&my_ip)); + } else { + os_sprintf(response, "Not connected to AP\r\n"); + } + to_console(response); + if (config.ap_on) + os_sprintf(response, "%d Station%s connected to AP\r\n", + wifi_softap_get_station_num(), wifi_softap_get_station_num() == 1 ? "" : "s"); + else + os_sprintf(response, "AP disabled\r\n"); + to_console(response); +#ifdef NTP + if (ntp_sync_done()) { + os_sprintf(response, "NTP synced: %s \r\n", get_timestr()); + } else { + os_sprintf(response, "NTP no sync\r\n"); + } + to_console(response); +#endif + goto command_handled_2; + } + + if (nTokens == 2 && strcmp(tokens[1], "mqtt") == 0) { + if (config.locked) { + os_sprintf(response, INVALID_LOCKED); + goto command_handled; + } + + MQTT_ClientCon *clientcon; + int ccnt = 0; + + os_sprintf(response, "Current clients: %d\r\n", MQTT_server_countClientCon()); + to_console(response); + for (clientcon = clientcon_list; clientcon != NULL; clientcon = clientcon->next, ccnt++) { + os_sprintf(response, "%s%s", clientcon->connect_info.client_id, clientcon->next != NULL ? ", " : ""); + to_console(response); + } + os_sprintf(response, "%sCurrent subsriptions:\r\n", ccnt ? "\r\n" : ""); + to_console(response); + iterate_topics(printf_topic, response); + os_sprintf(response, "Retained topics:\r\n"); + to_console(response); + iterate_retainedtopics(printf_retainedtopic, response); +#ifdef MQTT_CLIENT + os_sprintf(response, "MQTT client %s\r\n", mqtt_connected ? "connected" : "disconnected"); + to_console(response); +#endif +#ifdef SCRIPTED + os_sprintf(response, "Script %s\r\n", script_enabled ? "enabled" : "disabled"); + to_console(response); +#endif + goto command_handled_2; + } +#ifdef SCRIPTED + if (nTokens >= 2 && strcmp(tokens[1], "script") == 0) { + if (config.locked) { + os_sprintf(response, INVALID_LOCKED); + goto command_handled; + } + + uint32_t line_count, char_count, start_line = 1; + if (nTokens == 3) + start_line = atoi(tokens[2]); + + uint32_t size = get_script_size(); + if (size == 0) + goto command_handled; + + uint8_t *script = (uint8_t *) os_malloc(size); + uint8_t *p; + bool nl; + + if (script == 0) { + os_sprintf(response, "Out of memory"); + goto command_handled; + } + + blob_load(SCRIPT_SLOT, (uint32_t *) script, size); + + p = script + 4; + for (line_count = 1; line_count < start_line && *p != 0; p++) { + if (*p == '\n') + line_count++; + } + nl = true; + for (char_count = 0; *p != 0 && char_count < MAX_CON_SEND_SIZE - 20; p++, char_count++) { + if (nl) { + os_sprintf(response, "\r%4d: ", line_count); + char_count += 7; + to_console(response); + line_count++; + nl = false; + } + ringbuf_memcpy_into(console_tx_buffer, p, 1); + if (*p == '\n') + nl = true; + } + if (*p == 0) { + ringbuf_memcpy_into(console_tx_buffer, "\r\n--end--", 9); + } else { + ringbuf_memcpy_into(console_tx_buffer, "...", 3); + } + ringbuf_memcpy_into(console_tx_buffer, "\r\n", 2); + + os_free(script); + goto command_handled_2; + } + + if (nTokens >= 2 && strcmp(tokens[1], "vars") == 0) { + if (config.locked) { + os_sprintf(response, INVALID_LOCKED); + goto command_handled; + } + int i; + + if (script_enabled) { + for (i = 0; i < MAX_VARS; i++) { + if (!vars[i].free) { + os_sprintf(response, "%s: %s\r\n", vars[i].name, vars[i].data); + to_console(response); + } + } + } + + uint8_t slots[MAX_FLASH_SLOTS*FLASH_SLOT_LEN]; + blob_load(VARS_SLOT, (uint32_t *)slots, sizeof(slots)); + + for (i = 0; i < MAX_FLASH_SLOTS; i++) { + os_sprintf(response, "@%d: %s\r\n", i+1, &slots[i*FLASH_SLOT_LEN]); + to_console(response); + } + goto command_handled_2; + } +#endif + } + + if (strcmp(tokens[0], "save") == 0) { + if (config.locked) { + os_sprintf(response, INVALID_LOCKED); + goto command_handled; + } + + if (nTokens == 1 || (nTokens == 2 && strcmp(tokens[1], "config") == 0)) { + config_save(&config); + os_sprintf(response, "Config saved\r\n"); + goto command_handled; + } + } +#ifdef ALLOW_SCANNING + if (strcmp(tokens[0], "scan") == 0) { + wifi_station_scan(NULL, scan_done); + os_sprintf(response, "Scanning...\r\n"); + goto command_handled; + } +#endif +#ifdef NTP + if (strcmp(tokens[0], "time") == 0) { + os_sprintf(response, "%s %s\r\n", get_weekday(), get_timestr()); + goto command_handled; + } +#endif + if (strcmp(tokens[0], "reset") == 0) { + if (config.locked && pespconn != NULL) { + os_sprintf(response, INVALID_LOCKED); + goto command_handled; + } + if (nTokens == 2 && strcmp(tokens[1], "factory") == 0) { + config_load_default(&config); + config_save(&config); +#ifdef SCRIPTED + // Clear script, vars, and retained topics + blob_zero(SCRIPT_SLOT, MAX_SCRIPT_SIZE); + blob_zero(VARS_SLOT, MAX_FLASH_SLOTS * FLASH_SLOT_LEN); + blob_zero(RETAINED_SLOT, MAX_RETAINED_LEN); +#endif + } + + save_retainedtopics(); + + os_printf("Restarting ... \r\n"); + system_restart(); // if it works this will not return + + os_sprintf(response, "Reset failed\r\n"); + goto command_handled; + } + + if (strcmp(tokens[0], "quit") == 0) { + remote_console_disconnect = 1; + os_sprintf(response, "Quitting console\r\n"); + goto command_handled; + } +#ifdef SCRIPTED + if (strcmp(tokens[0], "script") == 0) { + uint16_t port; + + if (config.locked) { + os_sprintf(response, INVALID_LOCKED); + goto command_handled; + } + + if (nTokens != 2) { + os_sprintf(response, INVALID_NUMARGS); + goto command_handled; + } + + if (strcmp(tokens[1], "delete") == 0) { +#ifdef GPIO + stop_gpios(); +#endif + script_enabled = false; + if (my_script != NULL) + free_script(); + blob_zero(0, MAX_SCRIPT_SIZE); + blob_zero(1, MAX_FLASH_SLOTS * FLASH_SLOT_LEN); + os_sprintf(response, "Script deleted\r\n"); + goto command_handled; + } + + if (!isdigit(tokens[1][0])) { + scriptcon = pespconn; + http_get(tokens[1], "", http_script_cb); + os_sprintf(response, "HTTP request to %s started\r\n", tokens[1]); + goto command_handled; + } + + port = atoi(tokens[1]); + if (port == 0) { + os_sprintf(response, "Invalid port\r\n"); + goto command_handled; + } + // delete and disable existing script +#ifdef GPIO + stop_gpios(); +#endif + script_enabled = false; + if (my_script != NULL) + free_script(); + + scriptcon = pespconn; + downloadCon = (struct espconn *)os_zalloc(sizeof(struct espconn)); + + /* Equivalent to bind */ + downloadCon->type = ESPCONN_TCP; + downloadCon->state = ESPCONN_NONE; + downloadCon->proto.tcp = (esp_tcp *) os_zalloc(sizeof(esp_tcp)); + downloadCon->proto.tcp->local_port = port; + + /* Register callback when clients connect to the server */ + espconn_regist_connectcb(downloadCon, script_connected_cb); + + /* Put the connection in accept mode */ + espconn_accept(downloadCon); + + os_sprintf(response, "Waiting for script upload on port %d\r\n", port); + goto command_handled; + } +#endif + if (strcmp(tokens[0], "lock") == 0) { + if (config.locked) { + os_sprintf(response, "Config already locked\r\n"); + goto command_handled; + } + if (nTokens == 1) { + if (os_strlen(config.lock_password) == 0) { + os_sprintf(response, "No password defined\r\n"); + goto command_handled; + } + } + else if (nTokens == 2) { + os_sprintf(config.lock_password, "%s", tokens[1]); + } + else { + os_sprintf(response, INVALID_NUMARGS); + goto command_handled; + } + config.locked = 1; + config_save(&config); + os_sprintf(response, "Config locked (pw: %s)\r\n", config.lock_password); + goto command_handled; + } + + if (strcmp(tokens[0], "unlock") == 0) { + if (nTokens != 2) { + os_sprintf(response, INVALID_NUMARGS); + } else if (os_strcmp(tokens[1], config.lock_password) == 0) { + config.locked = 0; + config_save(&config); + os_sprintf(response, "Config unlocked\r\n"); + } else { + os_sprintf(response, "Unlock failed. Invalid password\r\n"); + } + goto command_handled; + } + + if (strcmp(tokens[0], "publish") == 0) + { + if (config.locked) { + os_sprintf(response, INVALID_LOCKED); + goto command_handled; + } + + uint8_t retained = 0; + + if (nTokens < 4 || nTokens > 5) { + os_sprintf(response, INVALID_NUMARGS); + goto command_handled; + } + if (nTokens == 5) { + if (strcmp(tokens[4], "retained")==0) { + retained = 1; + } else { + os_sprintf(response, "Invalid arg %s\r\n", tokens[4]); + goto command_handled; + } + } + if (strcmp(tokens[1], "local") == 0) { + MQTT_local_publish(tokens[2], tokens[3], os_strlen(tokens[3]), 0, retained); + } +#ifdef MQTT_CLIENT + else if (strcmp(tokens[1], "remote") == 0 && mqtt_connected) { + MQTT_Publish(&mqttClient, tokens[2], tokens[3], os_strlen(tokens[3]), 0, retained); + } +#endif + else { + os_sprintf(response, "Invalid arg %s\r\n", tokens[1]); + goto command_handled; + } + os_sprintf(response, "Published topic\r\n"); + goto command_handled; + } + + if (strcmp(tokens[0], "delete_retained") == 0) + { + if (config.locked) { + os_sprintf(response, INVALID_LOCKED); + goto command_handled; + } + + if (nTokens != 1) { + os_sprintf(response, INVALID_NUMARGS); + goto command_handled; + } + + delete_retainedtopics(); + + os_sprintf(response, "Deleted retained topics\r\n"); + goto command_handled; + } + + if (strcmp(tokens[0], "save_retained") == 0) + { + if (config.locked) { + os_sprintf(response, INVALID_LOCKED); + goto command_handled; + } + + if (nTokens != 1) { + os_sprintf(response, INVALID_NUMARGS); + goto command_handled; + } + + bool success = save_retainedtopics(); + + os_sprintf(response, "Saved retained topics %ssuccessfully\r\n", success?"":"un"); + goto command_handled; + } +/* + if (strcmp(tokens[0], "load_retained") == 0) + { + if (nTokens != 1) { + os_sprintf(response, INVALID_NUMARGS); + goto command_handled; + } + + bool success = load_retainedtopics(); + + os_sprintf(response, "Loaded retained topics %ssuccessfully\r\n", success?"":"un"); + goto command_handled; + } +*/ + if (strcmp(tokens[0], "set") == 0) { + if (config.locked) { + os_sprintf(response, INVALID_LOCKED); + goto command_handled; + } + + /* + * For set commands atleast 2 tokens "set" "parameter" "value" is needed + * hence the check + */ + if (nTokens < 3) { + os_sprintf(response, INVALID_NUMARGS); + goto command_handled; + } else { + // atleast 3 tokens, proceed + if (strcmp(tokens[1], "ssid") == 0) { + os_sprintf(config.ssid, "%s", tokens[2]); + config.auto_connect = 1; + os_sprintf(response, "SSID set (auto_connect = 1)\r\n"); + goto command_handled; + } + + if (strcmp(tokens[1], "password") == 0) { + os_sprintf(config.password, "%s", tokens[2]); + os_sprintf(response, "Password set\r\n"); + goto command_handled; + } + + if (strcmp(tokens[1], "auto_connect") == 0) { + config.auto_connect = atoi(tokens[2]); + os_sprintf(response, "Auto Connect set\r\n"); + goto command_handled; + } + + if (strcmp(tokens[1], "ap_ssid") == 0) { + os_sprintf(config.ap_ssid, "%s", tokens[2]); + os_sprintf(response, "AP SSID set\r\n"); + goto command_handled; + } + + if (strcmp(tokens[1], "ap_password") == 0) { + if (os_strlen(tokens[2]) < 8) { + os_sprintf(response, "Password to short (min. 8)\r\n"); + } else { + os_sprintf(config.ap_password, "%s", tokens[2]); + config.ap_open = 0; + os_sprintf(response, "AP Password set\r\n"); + } + goto command_handled; + } + + if (strcmp(tokens[1], "ap_open") == 0) { + config.ap_open = atoi(tokens[2]); + os_sprintf(response, "Open Auth set\r\n"); + goto command_handled; + } + + if (strcmp(tokens[1], "ap_on") == 0) { + if (atoi(tokens[2])) { + if (!config.ap_on) { + wifi_set_opmode(STATIONAP_MODE); + user_set_softap_wifi_config(); + do_ip_config = true; + config.ap_on = true; + os_sprintf(response, "AP on\r\n"); + } else { + os_sprintf(response, "AP already on\r\n"); + } + + } else { + if (config.ap_on) { + wifi_set_opmode(STATION_MODE); +#ifdef MDNS + if (config.mdns_mode == 2) { + espconn_mdns_close(); + } +#endif + config.ap_on = false; + os_sprintf(response, "AP off\r\n"); + } else { + os_sprintf(response, "AP already off\r\n"); + } + } + goto command_handled; + } + + if (strcmp(tokens[1], "speed") == 0) { + uint16_t speed = atoi(tokens[2]); + bool succ = system_update_cpu_freq(speed); + if (succ) + config.clock_speed = speed; + os_sprintf(response, "Clock speed update %s\r\n", succ ? "successful" : "failed"); + goto command_handled; + } + + if (strcmp(tokens[1],"bitrate") == 0) + { + config.bit_rate = atoi(tokens[2]); + os_sprintf(response, "Bitrate set to %d\r\n", config.bit_rate); + goto command_handled; + } + + if (strcmp(tokens[1],"system_output") == 0) + { + config.system_output = atoi(tokens[2]); + os_sprintf(response, "System output %s\r\n", config.system_output?"on":"off"); + goto command_handled; + } + + if (strcmp(tokens[1], "network") == 0) { + config.network_addr.addr = ipaddr_addr(tokens[2]); + ip4_addr4(&config.network_addr) = 0; + os_sprintf(response, "Network set to %d.%d.%d.%d\r\n", IP2STR(&config.network_addr)); + goto command_handled; + } + + if (strcmp(tokens[1], "dns") == 0) { + if (os_strcmp(tokens[2], "dhcp") == 0) { + config.dns_addr.addr = 0; + os_sprintf(response, "DNS from DHCP\r\n"); + } else { + config.dns_addr.addr = ipaddr_addr(tokens[2]); + os_sprintf(response, "DNS set to %d.%d.%d.%d\r\n", IP2STR(&config.dns_addr)); + if (config.dns_addr.addr) { + dns_ip.addr = config.dns_addr.addr; + } + } + goto command_handled; + } + + if (strcmp(tokens[1], "ip") == 0) { + if (os_strcmp(tokens[2], "dhcp") == 0) { + config.my_addr.addr = 0; + os_sprintf(response, "IP from DHCP\r\n"); + } else { + config.my_addr.addr = ipaddr_addr(tokens[2]); + os_sprintf(response, "IP address set to %d.%d.%d.%d\r\n", IP2STR(&config.my_addr)); + } + goto command_handled; + } + + if (strcmp(tokens[1], "netmask") == 0) { + config.my_netmask.addr = ipaddr_addr(tokens[2]); + os_sprintf(response, "IP netmask set to %d.%d.%d.%d\r\n", IP2STR(&config.my_netmask)); + goto command_handled; + } + + if (strcmp(tokens[1], "gw") == 0) { + config.my_gw.addr = ipaddr_addr(tokens[2]); + os_sprintf(response, "Gateway set to %d.%d.%d.%d\r\n", IP2STR(&config.my_gw)); + goto command_handled; + } +#ifdef MDNS + if (strcmp(tokens[1], "mdns_mode") == 0) { + config.mdns_mode = atoi(tokens[2]); + os_sprintf(response, "mDNS mode set to %d\r\n", config.mdns_mode); + goto command_handled; + } +#endif +#ifdef REMOTE_CONFIG + if (strcmp(tokens[1], "config_port") == 0) { + config.config_port = atoi(tokens[2]); + if (config.config_port == 0) + os_sprintf(response, "WARNING: if you save this, remote console access will be disabled!\r\n"); + else + os_sprintf(response, "Config port set to %d\r\n", config.config_port); + goto command_handled; + } + + if (strcmp(tokens[1], "config_access") == 0) { + config.config_access = atoi(tokens[2]) & (LOCAL_ACCESS | REMOTE_ACCESS); + if (config.config_access == 0) + os_sprintf(response, "WARNING: if you save this, remote console access will be disabled!\r\n"); + else + os_sprintf(response, "Config access set\r\n"); + goto command_handled; + } +#endif + if (strcmp(tokens[1], "broker_subscriptions") == 0) { + config.max_subscriptions = atoi(tokens[2]); + os_sprintf(response, "Broker subscriptions set\r\n"); + goto command_handled; + } + + if (strcmp(tokens[1], "broker_retained_messages") == 0) { + config.max_retained_messages = atoi(tokens[2]); + os_sprintf(response, "Broker retained messages set\r\n"); + goto command_handled; + } + + if (strcmp(tokens[1], "broker_clients") == 0) { + config.max_clients = atoi(tokens[2]); + os_sprintf(response, "Broker max clients set\r\n"); + goto command_handled; + } + + if (strcmp(tokens[1], "broker_user") == 0) { + os_strncpy(config.mqtt_broker_user, tokens[2], 32); + config.mqtt_broker_user[31] = '\0'; + os_sprintf(response, "Broker username set\r\n"); + goto command_handled; + } + + if (strcmp(tokens[1], "broker_password") == 0) { + if (os_strcmp(tokens[2], "none") == 0) { + config.mqtt_broker_password[0] = '\0'; + } else { + os_strncpy(config.mqtt_broker_password, tokens[2], 32); + config.mqtt_broker_password[31] = '\0'; + } + os_sprintf(response, "Broker password set\r\n"); + goto command_handled; + } + + if (strcmp(tokens[1], "broker_access") == 0) { + config.mqtt_broker_access = atoi(tokens[2]) & (LOCAL_ACCESS | REMOTE_ACCESS); + os_sprintf(response, "Broker access set\r\n", config.config_port); + goto command_handled; + } + + if (strcmp(tokens[1], "broker_autoretain") == 0) { + config.auto_retained = atoi(tokens[2]) != 0; + os_sprintf(response, "Broker autoretain set\r\n", config.config_port); + goto command_handled; + } +#ifdef SCRIPTED + if (strcmp(tokens[1], "script_logging") == 0) { + lang_logging = atoi(tokens[2]); + os_sprintf(response, "Script logging set\r\n"); + goto command_handled; + } + + if (tokens[1][0] == '@') { + uint32_t slot_no = atoi(&tokens[1][1]); + if (slot_no == 0 || slot_no > MAX_FLASH_SLOTS) { + os_sprintf(response, "Invalid flash slot number"); + } else { + slot_no--; + uint8_t slots[MAX_FLASH_SLOTS*FLASH_SLOT_LEN]; + blob_load(VARS_SLOT, (uint32_t *)slots, sizeof(slots)); + os_strcpy(&slots[slot_no*FLASH_SLOT_LEN], tokens[2]); + blob_save(VARS_SLOT, (uint32_t *)slots, sizeof(slots)); + os_sprintf(response, "%s written to flash\r\n", tokens[1]); + } + goto command_handled; + } +#ifdef GPIO +#ifdef GPIO_PWM + if (strcmp(tokens[1], "pwm_period") == 0) { + config.pwm_period = atoi(tokens[2]); + os_sprintf(response, "PWM period set\r\n"); + goto command_handled; + } +#endif +#endif +#endif +#ifdef NTP + if (strcmp(tokens[1], "ntp_server") == 0) { + os_strncpy(config.ntp_server, tokens[2], 32); + config.ntp_server[31] = 0; + ntp_set_server(config.ntp_server); + os_sprintf(response, "NTP server set to %s\r\n", config.ntp_server); + goto command_handled; + } + + if (strcmp(tokens[1], "ntp_interval") == 0) { + config.ntp_interval = atoi(tokens[2]) * 1000000; + os_sprintf(response, "NTP interval set to %d s\r\n", atoi(tokens[2])); + goto command_handled; + } + + if (strcmp(tokens[1], "ntp_timezone") == 0) { + config.ntp_timezone = atoi(tokens[2]); + set_timezone(config.ntp_timezone); + os_sprintf(response, "NTP timezone set to %d h\r\n", config.ntp_timezone); + goto command_handled; + } +#endif +#ifdef MQTT_CLIENT + if (strcmp(tokens[1], "mqtt_host") == 0) { + os_strncpy(config.mqtt_host, tokens[2], 32); + config.mqtt_host[31] = 0; + os_sprintf(response, "MQTT host set\r\n"); + goto command_handled; + } + + if (strcmp(tokens[1], "mqtt_port") == 0) { + config.mqtt_port = atoi(tokens[2]); + os_sprintf(response, "MQTT port set\r\n"); + goto command_handled; + } + + if (strcmp(tokens[1], "mqtt_ssl") == 0) { + config.mqtt_ssl = atoi(tokens[2]); + os_sprintf(response, "MQTT ssl %s\r\n", config.mqtt_ssl?"on":"off"); + goto command_handled; + } + + if (strcmp(tokens[1], "mqtt_user") == 0) { + os_strncpy(config.mqtt_user, tokens[2], 32); + config.mqtt_user[31] = 0; + os_sprintf(response, "MQTT user set\r\n"); + goto command_handled; + } + + if (strcmp(tokens[1], "mqtt_password") == 0) { + os_strncpy(config.mqtt_password, tokens[2], 32); + config.mqtt_password[31] = 0; + os_sprintf(response, "MQTT password set\r\n"); + goto command_handled; + } + + if (strcmp(tokens[1], "mqtt_id") == 0) { + os_strncpy(config.mqtt_id, tokens[2], 32); + config.mqtt_id[31] = 0; + os_sprintf(response, "MQTT id set\r\n"); + goto command_handled; + } +#endif /* MQTT_CLIENT */ + } + + } + + /* Control comes here only if the tokens[0] command is not handled */ + os_sprintf(response, "\r\nInvalid Command\r\n"); + + command_handled: + to_console(response); + command_handled_2: + system_os_post(user_procTaskPrio, SIG_CONSOLE_TX, (ETSParam) pespconn); + return; +} diff --git a/user/global.h b/user/global.h new file mode 100644 index 0000000..75792f2 --- /dev/null +++ b/user/global.h @@ -0,0 +1,45 @@ +#include "user_interface.h" + +#include "ringbuf.h" +#include "user_config.h" +#include "config_flash.h" + +#include "mqtt/mqtt_server.h" +#include "mqtt/mqtt_topiclist.h" +#include "mqtt/mqtt_retainedlist.h" + +#ifdef SCRIPTED +#include "lang.h" +#include "pub_list.h" +#endif + +/* Hold the system wide configuration */ +#define user_procTaskPrio 0 + +extern sysconfig_t config; +extern ringbuf_t console_rx_buffer, console_tx_buffer; +extern struct espconn *console_conn; +extern uint8_t remote_console_disconnect; +extern bool mqtt_enabled, mqtt_connected; +extern ip_addr_t my_ip; +extern ip_addr_t dns_ip; +extern bool connected; +extern uint8_t my_channel; +extern bool do_ip_config; + +#ifdef MQTT_CLIENT +extern MQTT_Client mqttClient; +extern bool mqtt_enabled, mqtt_connected; +#endif + +#ifdef SCRIPTED +extern uint8_t *my_script; +extern struct espconn *downloadCon; +extern struct espconn *scriptcon; + +void http_script_cb(char *response_body, int http_status, char *response_headers, int body_size); +void script_connected_cb(void *arg); +#endif + +void console_handle_command(struct espconn *pespconn); +void to_console(char *str); diff --git a/user/lang.c b/user/lang.c index b9a226a..6ef412b 100644 --- a/user/lang.c +++ b/user/lang.c @@ -1189,6 +1189,82 @@ int ICACHE_FLASH_ATTR parse_expression(int next_token, char **data, int *data_le *data_type = STRING_T; } } + + else if (is_token(next_token, "csvstr")) { + lang_debug("val csvstr\r\n"); + + len_check(7); + if (syn_chk && !is_token(next_token+1, "(")) + return syntax_error(next_token+1, "expected '('"); + + char *str_data; + int str_data_len; + Value_Type str_data_type; + // parse path string + if ((next_token = parse_expression(next_token + 2, &str_data, &str_data_len, &str_data_type, doit)) == -1) + return -1; + if (!doit) + str_data_len = 0; + char str[str_data_len+1]; + if (doit) + os_strcpy(str, str_data); + + if (syn_chk && !is_token(next_token, ",")) + return syntax_error(next_token, "expected ','"); + next_token++; + + int16_t num = atoi(my_token[next_token]); + if (num == 0) + return syntax_error(next_token, "value > 0 expected"); + num--; + next_token++; + + if (syn_chk && !is_token(next_token, ",")) + return syntax_error(next_token, "expected ','"); + next_token++; + + uint8_t ch = my_token[next_token][0]; + // if as string const + if (my_token[next_token][0] == '"') + ch = my_token[next_token][1]; + next_token++; + + if (syn_chk && !is_token(next_token, ")")) + return syntax_error(next_token, "expected ')'"); + next_token++; + + if (doit) { + int i; + char *p, *q; + + for (i=0, p=q=str_data; i<=num; p++) { + if (*p == ch || *p == '\0') { + i++; + if (i > num) { + break; + } + q=p+1; + } + if (*p == '\0') + break; + } + + if (i<=num) { + *data_len = 0; + *data = ""; + } else { + uint16_t len = p-q; + if (len > sizeof(tmp_buffer)-1) + len = sizeof(tmp_buffer)-1; + os_strncpy(tmp_buffer, q, len); + tmp_buffer[len] = '\0'; + + *data_len = len; + *data = tmp_buffer; + } + *data_type = STRING_T; + } + } #ifdef GPIO else if (is_token(next_token, "gpio_in")) { lang_debug("val gpio_in\r\n"); diff --git a/user/user_main.c b/user/user_main.c index d069538..bb18b08 100644 --- a/user/user_main.c +++ b/user/user_main.c @@ -3,19 +3,12 @@ #include "ets_sys.h" #include "osapi.h" #include "os_type.h" +#include "sys_time.h" -#include "user_interface.h" #include "string.h" #include "driver/uart.h" -#include "ringbuf.h" -#include "user_config.h" -#include "config_flash.h" -#include "sys_time.h" - -#include "mqtt/mqtt_server.h" -#include "mqtt/mqtt_topiclist.h" -#include "mqtt/mqtt_retainedlist.h" +#include "global.h" #ifdef GPIO //#include "easygpio.h" @@ -57,10 +50,10 @@ uint64_t t_old; /* Hold the system wide configuration */ sysconfig_t config; -static ringbuf_t console_rx_buffer, console_tx_buffer; +ringbuf_t console_rx_buffer, console_tx_buffer; -static ip_addr_t my_ip; -static ip_addr_t dns_ip; +ip_addr_t my_ip; +ip_addr_t dns_ip; bool connected; uint8_t my_channel; bool do_ip_config; @@ -96,7 +89,6 @@ bool ICACHE_FLASH_ATTR check_connection_access(struct espconn *pesp_conn, uint8_ } #ifdef MQTT_CLIENT - MQTT_Client mqttClient; bool mqtt_enabled, mqtt_connected; @@ -209,7 +201,7 @@ static void ICACHE_FLASH_ATTR script_discon_cb(void *arg) { } /* Called when a client connects to the script server */ -static void ICACHE_FLASH_ATTR script_connected_cb(void *arg) { +void ICACHE_FLASH_ATTR script_connected_cb(void *arg) { char response[64]; struct espconn *pespconn = (struct espconn *)arg; @@ -262,64 +254,6 @@ void ICACHE_FLASH_ATTR free_script(void) { } #endif /* SCRIPTED */ -int ICACHE_FLASH_ATTR parse_str_into_tokens(char *str, char **tokens, int max_tokens) -{ -char *p, *q, *end; -int token_count = 0; -bool in_token = false; - - // preprocessing - for (p = q = str; *p != 0; p++) { - if (*(p) == '%' && *(p+1) != 0 && *(p+2) != 0) { - // quoted hex - uint8_t a; - p++; - if (*p <= '9') - a = *p - '0'; - else - a = toupper(*p) - 'A' + 10; - a <<= 4; - p++; - if (*p <= '9') - a += *p - '0'; - else - a += toupper(*p) - 'A' + 10; - *q++ = a; - } else if (*p == '\\' && *(p+1) != 0) { - // next char is quoted - just copy it, skip this one - *q++ = *++p; - } else if (*p == 8) { - // backspace - delete previous char - if (q != str) q--; - } else if (*p <= ' ') { - // mark this as whitespace - *q++ = 0; - } else { - *q++ = *p; - } - } - - end = q; - *q = 0; - - // cut into tokens - for (p = str; p != end; p++) { - if (*p == 0) { - if (in_token) { - in_token = false; - } - } else { - if (!in_token) { - tokens[token_count++] = p; - if (token_count == max_tokens) - return token_count; - in_token = true; - } - } - } - return token_count; -} - void ICACHE_FLASH_ATTR console_send_response(struct espconn *pespconn) { char payload[MAX_CON_SEND_SIZE]; uint16_t len = ringbuf_bytes_used(console_tx_buffer); @@ -338,51 +272,11 @@ void ICACHE_FLASH_ATTR console_send_response(struct espconn *pespconn) { } } -#ifdef ALLOW_SCANNING -void ICACHE_FLASH_ATTR scan_done(void *arg, STATUS status) { - char response[128]; - - if (status == OK) { - struct bss_info *bss_link = (struct bss_info *)arg; - - ringbuf_memcpy_into(console_tx_buffer, "\r", 1); - while (bss_link != NULL) { - os_sprintf(response, "%d,\"%s\",%d,\"" MACSTR "\",%d\r\n", - bss_link->authmode, bss_link->ssid, bss_link->rssi, MAC2STR(bss_link->bssid), bss_link->channel); - to_console(response); - bss_link = bss_link->next.stqe_next; - } - } else { - os_sprintf(response, "scan fail !!!\r\n"); - to_console(response); - } - system_os_post(user_procTaskPrio, SIG_CONSOLE_TX, (ETSParam) console_conn); -} -#endif - void ICACHE_FLASH_ATTR con_print(uint8_t *str) { ringbuf_memcpy_into(console_tx_buffer, str, os_strlen(str)); system_os_post(user_procTaskPrio, SIG_CONSOLE_TX_RAW, (ETSParam) console_conn); } -bool ICACHE_FLASH_ATTR printf_topic(topic_entry * topic, void *user_data) { - uint8_t *response = (uint8_t *) user_data; - - os_sprintf(response, "%s: \"%s\" (QoS %d)\r\n", - topic->clientcon != - LOCAL_MQTT_CLIENT ? topic->clientcon->connect_info.client_id : "local", topic->topic, topic->qos); - to_console(response); - return false; -} - -bool ICACHE_FLASH_ATTR printf_retainedtopic(retained_entry * entry, void *user_data) { - uint8_t *response = (uint8_t *) user_data; - - os_sprintf(response, "\"%s\" len: %d (QoS %d)\r\n", entry->topic, entry->data_len, entry->qos); - to_console(response); - return false; -} - bool ICACHE_FLASH_ATTR delete_retainedtopics() { clear_retainedtopics(); blob_zero(RETAINED_SLOT, MAX_RETAINED_LEN); @@ -417,903 +311,6 @@ void MQTT_local_DataCallback(uint32_t * args, const char *topic, uint32_t topic_ #endif } - -static char INVALID_LOCKED[] = "Invalid command. Config locked\r\n"; -static char INVALID_NUMARGS[] = "Invalid number of arguments\r\n"; -static char INVALID_ARG[] = "Invalid argument\r\n"; - -void ICACHE_FLASH_ATTR console_handle_command(struct espconn *pespconn) { -#define MAX_CMD_TOKENS 6 - - char cmd_line[MAX_CON_CMD_SIZE + 1]; - char response[256]; - char *tokens[MAX_CMD_TOKENS]; - - int bytes_count, nTokens; - - bytes_count = ringbuf_bytes_used(console_rx_buffer); - ringbuf_memcpy_from(cmd_line, console_rx_buffer, bytes_count); - - cmd_line[bytes_count] = 0; - response[0] = 0; - - nTokens = parse_str_into_tokens(cmd_line, tokens, MAX_CMD_TOKENS); - - if (nTokens == 0) { - char c = '\n'; - ringbuf_memcpy_into(console_tx_buffer, &c, 1); - goto command_handled_2; - } - - if (strcmp(tokens[0], "help") == 0) { - os_sprintf(response, "show [config|stats|mqtt]\r\nsave\r\nreset [factory]\r\nlock [<password>]\r\nunlock <password>\r\nquit\r\n"); - to_console(response); -#ifdef ALLOW_SCANNING - os_sprintf(response, "scan\r\n"); - to_console(response); -#endif - os_sprintf(response, "set [ssid|password|auto_connect|ap_ssid|ap_password|ap_on|ap_open] <val>\r\n"); - to_console(response); - os_sprintf(response, "set [network|dns|ip|netmask|gw] <val>\r\n"); - to_console(response); - os_sprintf(response, "set [config_port|config_access|bitrate|system_output] <val>\r\n"); - to_console(response); - os_sprintf(response, "set [broker_user|broker_password|broker_access|broker_clients] <val>\r\n"); - to_console(response); - os_sprintf(response, "set [broker_subscriptions|broker_retained_messages|broker_autoretain] <val>\r\n"); - to_console(response); - os_sprintf(response, "delete_retained|save_retained\r\n"); - to_console(response); - os_sprintf(response, "publish [local|remote] <topic> <data> [retained]\r\n"); - to_console(response); -#ifdef SCRIPTED - os_sprintf(response, "script <port>|<url>|delete\r\nshow [script|vars]\r\n"); - to_console(response); -#ifdef GPIO -#ifdef GPIO_PWM - os_sprintf(response, "set pwm_period <val>\r\n"); - to_console(response); -#endif -#endif -#endif -#ifdef NTP - os_sprintf(response, "time\r\nset [ntp_server|ntp_interval|<ntp_timezone> <val>\r\n"); - to_console(response); -#endif -#ifdef MQTT_CLIENT - os_sprintf(response, "set [mqtt_host|mqtt_port|mqtt_ssl|mqtt_user|mqtt_password|mqtt_id] <val>\r\n"); - to_console(response); -#endif - - goto command_handled_2; - } - - if (strcmp(tokens[0], "show") == 0) { - int16_t i; - ip_addr_t i_ip; - - if (nTokens == 1 || (nTokens == 2 && strcmp(tokens[1], "config") == 0)) { - os_sprintf(response, "STA: SSID:%s PW:%s%s\r\n", - config.ssid, - config.locked ? "***" : (char *)config.password, config.auto_connect ? "" : " [AutoConnect:0]"); - to_console(response); - - os_sprintf(response, "AP: SSID:%s PW:%s%s%s IP:%d.%d.%d.%d/24\r\n", - config.ap_ssid, - config.locked ? "***" : (char *)config.ap_password, - config.ap_open ? " [open]" : "", - config.ap_on ? "" : " [disabled]", IP2STR(&config.network_addr)); - to_console(response); - - // if static IP, add it - os_sprintf(response, - config.my_addr.addr ? - "Static IP: %d.%d.%d.%d Netmask: %d.%d.%d.%d Gateway: %d.%d.%d.%d\r\n" - : "", IP2STR(&config.my_addr), IP2STR(&config.my_netmask), IP2STR(&config.my_gw)); - to_console(response); - // if static DNS, add it - os_sprintf(response, config.dns_addr.addr ? "DNS: %d.%d.%d.%d\r\n" : "", IP2STR(&config.dns_addr)); - to_console(response); -#ifdef MDNS - if (config.mdns_mode) { - os_sprintf(response, "mDNS: %s interface\r\n", config.mdns_mode==1 ? "STA": "SoftAP"); - to_console(response); - } -#endif -#ifdef REMOTE_CONFIG - if (config.config_port == 0 || config.config_access == 0) { - os_sprintf(response, "No network console access\r\n"); - } else { - os_sprintf(response, "Network console access on port %d (mode %d)\r\n", config.config_port, config.config_access); - } - to_console(response); -#endif - - os_sprintf(response, "MQTT broker max. subscription: %d\r\nMQTT broker max. retained messages: %d%s\r\n", - config.max_subscriptions, config.max_retained_messages, config.auto_retained?" (auto saved)":""); - to_console(response); - - os_sprintf(response, "MQTT broker max. clients: %d\r\n", config.max_clients); - to_console(response); - - if (os_strcmp(config.mqtt_broker_user, "none") != 0) { - os_sprintf(response, - "MQTT broker username: %s\r\nMQTT broker password: %s\r\n", - config.mqtt_broker_user, - config.locked ? "***" : (char *)config.mqtt_broker_password); - to_console(response); - } - response[0] = '\0'; - if (config.mqtt_broker_access == LOCAL_ACCESS) - os_sprintf(response, "MQTT broker: local access only\r\n"); - if (config.mqtt_broker_access == REMOTE_ACCESS) - os_sprintf(response, "MQTT broker: remote access only\r\n"); - if (config.mqtt_broker_access == 0) - os_sprintf(response, "MQTT broker: disabled\r\n"); - to_console(response); -#ifdef MQTT_CLIENT - os_sprintf(response, "MQTT client %s\r\n", mqtt_enabled ? "enabled" : "disabled"); - to_console(response); - - if (os_strcmp(config.mqtt_host, "none") != 0) { - os_sprintf(response, - "MQTT client host: %s\r\nMQTT client port: %d\r\nMQTT client user: %s\r\nMQTT client password: %s\r\nMQTT client id: %s\r\nMQTT SSL: %s\r\n", - config.mqtt_host, config.mqtt_port, config.mqtt_user, - config.locked ? "***" : (char *)config.mqtt_password, config.mqtt_id, - config.mqtt_ssl ? "on" : "off"); - to_console(response); - } -#endif -#ifdef NTP - if (os_strcmp(config.ntp_server, "none") != 0) { - os_sprintf(response, - "NTP server: %s (interval: %d s, tz: %d)\r\n", - config.ntp_server, config.ntp_interval / 1000000, config.ntp_timezone); - to_console(response); - } -#endif - os_sprintf(response, "Clock speed: %d\r\n", config.clock_speed); - to_console(response); - - os_sprintf(response, "Serial bitrate: %d\r\n", config.bit_rate); - to_console(response); - if (!config.system_output) - to_console("System output: off\r\n"); - - goto command_handled_2; - } - - if (nTokens == 2 && strcmp(tokens[1], "stats") == 0) { - uint32_t time = (uint32_t) (get_long_systime() / 1000000); - int16_t i; - - os_sprintf(response, "System uptime: %d:%02d:%02d\r\n", time / 3600, (time % 3600) / 60, time % 60); - to_console(response); - - os_sprintf(response, "Free mem: %d\r\n", system_get_free_heap_size()); - to_console(response); -#ifdef SCRIPTED - os_sprintf(response, "Interpreter loop: %d us\r\n", loop_time); - to_console(response); -#endif - if (connected) { - os_sprintf(response, "External IP-address: " IPSTR "\r\n", IP2STR(&my_ip)); - } else { - os_sprintf(response, "Not connected to AP\r\n"); - } - to_console(response); - if (config.ap_on) - os_sprintf(response, "%d Station%s connected to AP\r\n", - wifi_softap_get_station_num(), wifi_softap_get_station_num() == 1 ? "" : "s"); - else - os_sprintf(response, "AP disabled\r\n"); - to_console(response); -#ifdef NTP - if (ntp_sync_done()) { - os_sprintf(response, "NTP synced: %s \r\n", get_timestr()); - } else { - os_sprintf(response, "NTP no sync\r\n"); - } - to_console(response); -#endif - goto command_handled_2; - } - - if (nTokens == 2 && strcmp(tokens[1], "mqtt") == 0) { - if (config.locked) { - os_sprintf(response, INVALID_LOCKED); - goto command_handled; - } - - MQTT_ClientCon *clientcon; - int ccnt = 0; - - os_sprintf(response, "Current clients: %d\r\n", MQTT_server_countClientCon()); - to_console(response); - for (clientcon = clientcon_list; clientcon != NULL; clientcon = clientcon->next, ccnt++) { - os_sprintf(response, "%s%s", clientcon->connect_info.client_id, clientcon->next != NULL ? ", " : ""); - to_console(response); - } - os_sprintf(response, "%sCurrent subsriptions:\r\n", ccnt ? "\r\n" : ""); - to_console(response); - iterate_topics(printf_topic, response); - os_sprintf(response, "Retained topics:\r\n"); - to_console(response); - iterate_retainedtopics(printf_retainedtopic, response); -#ifdef MQTT_CLIENT - os_sprintf(response, "MQTT client %s\r\n", mqtt_connected ? "connected" : "disconnected"); - to_console(response); -#endif -#ifdef SCRIPTED - os_sprintf(response, "Script %s\r\n", script_enabled ? "enabled" : "disabled"); - to_console(response); -#endif - goto command_handled_2; - } -#ifdef SCRIPTED - if (nTokens >= 2 && strcmp(tokens[1], "script") == 0) { - if (config.locked) { - os_sprintf(response, INVALID_LOCKED); - goto command_handled; - } - - uint32_t line_count, char_count, start_line = 1; - if (nTokens == 3) - start_line = atoi(tokens[2]); - - uint32_t size = get_script_size(); - if (size == 0) - goto command_handled; - - uint8_t *script = (uint8_t *) os_malloc(size); - uint8_t *p; - bool nl; - - if (script == 0) { - os_sprintf(response, "Out of memory"); - goto command_handled; - } - - blob_load(SCRIPT_SLOT, (uint32_t *) script, size); - - p = script + 4; - for (line_count = 1; line_count < start_line && *p != 0; p++) { - if (*p == '\n') - line_count++; - } - nl = true; - for (char_count = 0; *p != 0 && char_count < MAX_CON_SEND_SIZE - 20; p++, char_count++) { - if (nl) { - os_sprintf(response, "\r%4d: ", line_count); - char_count += 7; - to_console(response); - line_count++; - nl = false; - } - ringbuf_memcpy_into(console_tx_buffer, p, 1); - if (*p == '\n') - nl = true; - } - if (*p == 0) { - ringbuf_memcpy_into(console_tx_buffer, "\r\n--end--", 9); - } else { - ringbuf_memcpy_into(console_tx_buffer, "...", 3); - } - ringbuf_memcpy_into(console_tx_buffer, "\r\n", 2); - - os_free(script); - goto command_handled_2; - } - - if (nTokens >= 2 && strcmp(tokens[1], "vars") == 0) { - if (config.locked) { - os_sprintf(response, INVALID_LOCKED); - goto command_handled; - } - int i; - - if (script_enabled) { - for (i = 0; i < MAX_VARS; i++) { - if (!vars[i].free) { - os_sprintf(response, "%s: %s\r\n", vars[i].name, vars[i].data); - to_console(response); - } - } - } - - uint8_t slots[MAX_FLASH_SLOTS*FLASH_SLOT_LEN]; - blob_load(VARS_SLOT, (uint32_t *)slots, sizeof(slots)); - - for (i = 0; i < MAX_FLASH_SLOTS; i++) { - os_sprintf(response, "@%d: %s\r\n", i+1, &slots[i*FLASH_SLOT_LEN]); - to_console(response); - } - goto command_handled_2; - } -#endif - } - - if (strcmp(tokens[0], "save") == 0) { - if (config.locked) { - os_sprintf(response, INVALID_LOCKED); - goto command_handled; - } - - if (nTokens == 1 || (nTokens == 2 && strcmp(tokens[1], "config") == 0)) { - config_save(&config); - os_sprintf(response, "Config saved\r\n"); - goto command_handled; - } - } -#ifdef ALLOW_SCANNING - if (strcmp(tokens[0], "scan") == 0) { - wifi_station_scan(NULL, scan_done); - os_sprintf(response, "Scanning...\r\n"); - goto command_handled; - } -#endif -#ifdef NTP - if (strcmp(tokens[0], "time") == 0) { - os_sprintf(response, "%s %s\r\n", get_weekday(), get_timestr()); - goto command_handled; - } -#endif - if (strcmp(tokens[0], "reset") == 0) { - if (config.locked && pespconn != NULL) { - os_sprintf(response, INVALID_LOCKED); - goto command_handled; - } - if (nTokens == 2 && strcmp(tokens[1], "factory") == 0) { - config_load_default(&config); - config_save(&config); -#ifdef SCRIPTED - // Clear script, vars, and retained topics - blob_zero(SCRIPT_SLOT, MAX_SCRIPT_SIZE); - blob_zero(VARS_SLOT, MAX_FLASH_SLOTS * FLASH_SLOT_LEN); - blob_zero(RETAINED_SLOT, MAX_RETAINED_LEN); -#endif - } - - save_retainedtopics(); - - os_printf("Restarting ... \r\n"); - system_restart(); // if it works this will not return - - os_sprintf(response, "Reset failed\r\n"); - goto command_handled; - } - - if (strcmp(tokens[0], "quit") == 0) { - remote_console_disconnect = 1; - os_sprintf(response, "Quitting console\r\n"); - goto command_handled; - } -#ifdef SCRIPTED - if (strcmp(tokens[0], "script") == 0) { - uint16_t port; - - if (config.locked) { - os_sprintf(response, INVALID_LOCKED); - goto command_handled; - } - - if (nTokens != 2) { - os_sprintf(response, INVALID_NUMARGS); - goto command_handled; - } - - if (strcmp(tokens[1], "delete") == 0) { -#ifdef SCRIPTED -#ifdef GPIO - stop_gpios(); -#endif -#endif - script_enabled = false; - if (my_script != NULL) - free_script(); - blob_zero(0, MAX_SCRIPT_SIZE); - blob_zero(1, MAX_FLASH_SLOTS * FLASH_SLOT_LEN); - os_sprintf(response, "Script deleted\r\n"); - goto command_handled; - } - - if (!isdigit(tokens[1][0])) { - scriptcon = pespconn; - http_get(tokens[1], "", http_script_cb); - os_sprintf(response, "HTTP request to %s started\r\n", tokens[1]); - goto command_handled; - } - - port = atoi(tokens[1]); - if (port == 0) { - os_sprintf(response, "Invalid port\r\n"); - goto command_handled; - } - // delete and disable existing script -#ifdef SCRIPTED -#ifdef GPIO - stop_gpios(); -#endif -#endif - script_enabled = false; - if (my_script != NULL) - free_script(); - - scriptcon = pespconn; - downloadCon = (struct espconn *)os_zalloc(sizeof(struct espconn)); - - /* Equivalent to bind */ - downloadCon->type = ESPCONN_TCP; - downloadCon->state = ESPCONN_NONE; - downloadCon->proto.tcp = (esp_tcp *) os_zalloc(sizeof(esp_tcp)); - downloadCon->proto.tcp->local_port = port; - - /* Register callback when clients connect to the server */ - espconn_regist_connectcb(downloadCon, script_connected_cb); - - /* Put the connection in accept mode */ - espconn_accept(downloadCon); - - os_sprintf(response, "Waiting for script upload on port %d\r\n", port); - goto command_handled; - } -#endif - if (strcmp(tokens[0], "lock") == 0) { - if (config.locked) { - os_sprintf(response, "Config already locked\r\n"); - goto command_handled; - } - if (nTokens == 1) { - if (os_strlen(config.lock_password) == 0) { - os_sprintf(response, "No password defined\r\n"); - goto command_handled; - } - } - else if (nTokens == 2) { - os_sprintf(config.lock_password, "%s", tokens[1]); - } - else { - os_sprintf(response, INVALID_NUMARGS); - goto command_handled; - } - config.locked = 1; - config_save(&config); - os_sprintf(response, "Config locked (pw: %s)\r\n", config.lock_password); - goto command_handled; - } - - if (strcmp(tokens[0], "unlock") == 0) { - if (nTokens != 2) { - os_sprintf(response, INVALID_NUMARGS); - } else if (os_strcmp(tokens[1], config.lock_password) == 0) { - config.locked = 0; - config_save(&config); - os_sprintf(response, "Config unlocked\r\n"); - } else { - os_sprintf(response, "Unlock failed. Invalid password\r\n"); - } - goto command_handled; - } - - if (strcmp(tokens[0], "publish") == 0) - { - if (config.locked) { - os_sprintf(response, INVALID_LOCKED); - goto command_handled; - } - - uint8_t retained = 0; - - if (nTokens < 4 || nTokens > 5) { - os_sprintf(response, INVALID_NUMARGS); - goto command_handled; - } - if (nTokens == 5) { - if (strcmp(tokens[4], "retained")==0) { - retained = 1; - } else { - os_sprintf(response, "Invalid arg %s\r\n", tokens[4]); - goto command_handled; - } - } - if (strcmp(tokens[1], "local") == 0) { - MQTT_local_publish(tokens[2], tokens[3], os_strlen(tokens[3]), 0, retained); - } -#ifdef MQTT_CLIENT - else if (strcmp(tokens[1], "remote") == 0 && mqtt_connected) { - MQTT_Publish(&mqttClient, tokens[2], tokens[3], os_strlen(tokens[3]), 0, retained); - } -#endif - else { - os_sprintf(response, "Invalid arg %s\r\n", tokens[1]); - goto command_handled; - } - os_sprintf(response, "Published topic\r\n"); - goto command_handled; - } - - if (strcmp(tokens[0], "delete_retained") == 0) - { - if (config.locked) { - os_sprintf(response, INVALID_LOCKED); - goto command_handled; - } - - if (nTokens != 1) { - os_sprintf(response, INVALID_NUMARGS); - goto command_handled; - } - - delete_retainedtopics(); - - os_sprintf(response, "Deleted retained topics\r\n"); - goto command_handled; - } - - if (strcmp(tokens[0], "save_retained") == 0) - { - if (config.locked) { - os_sprintf(response, INVALID_LOCKED); - goto command_handled; - } - - if (nTokens != 1) { - os_sprintf(response, INVALID_NUMARGS); - goto command_handled; - } - - bool success = save_retainedtopics(); - - os_sprintf(response, "Saved retained topics %ssuccessfully\r\n", success?"":"un"); - goto command_handled; - } -/* - if (strcmp(tokens[0], "load_retained") == 0) - { - if (nTokens != 1) { - os_sprintf(response, INVALID_NUMARGS); - goto command_handled; - } - - bool success = load_retainedtopics(); - - os_sprintf(response, "Loaded retained topics %ssuccessfully\r\n", success?"":"un"); - goto command_handled; - } -*/ - if (strcmp(tokens[0], "set") == 0) { - if (config.locked) { - os_sprintf(response, INVALID_LOCKED); - goto command_handled; - } - - /* - * For set commands atleast 2 tokens "set" "parameter" "value" is needed - * hence the check - */ - if (nTokens < 3) { - os_sprintf(response, INVALID_NUMARGS); - goto command_handled; - } else { - // atleast 3 tokens, proceed - if (strcmp(tokens[1], "ssid") == 0) { - os_sprintf(config.ssid, "%s", tokens[2]); - config.auto_connect = 1; - os_sprintf(response, "SSID set (auto_connect = 1)\r\n"); - goto command_handled; - } - - if (strcmp(tokens[1], "password") == 0) { - os_sprintf(config.password, "%s", tokens[2]); - os_sprintf(response, "Password set\r\n"); - goto command_handled; - } - - if (strcmp(tokens[1], "auto_connect") == 0) { - config.auto_connect = atoi(tokens[2]); - os_sprintf(response, "Auto Connect set\r\n"); - goto command_handled; - } - - if (strcmp(tokens[1], "ap_ssid") == 0) { - os_sprintf(config.ap_ssid, "%s", tokens[2]); - os_sprintf(response, "AP SSID set\r\n"); - goto command_handled; - } - - if (strcmp(tokens[1], "ap_password") == 0) { - if (os_strlen(tokens[2]) < 8) { - os_sprintf(response, "Password to short (min. 8)\r\n"); - } else { - os_sprintf(config.ap_password, "%s", tokens[2]); - config.ap_open = 0; - os_sprintf(response, "AP Password set\r\n"); - } - goto command_handled; - } - - if (strcmp(tokens[1], "ap_open") == 0) { - config.ap_open = atoi(tokens[2]); - os_sprintf(response, "Open Auth set\r\n"); - goto command_handled; - } - - if (strcmp(tokens[1], "ap_on") == 0) { - if (atoi(tokens[2])) { - if (!config.ap_on) { - wifi_set_opmode(STATIONAP_MODE); - user_set_softap_wifi_config(); - do_ip_config = true; - config.ap_on = true; - os_sprintf(response, "AP on\r\n"); - } else { - os_sprintf(response, "AP already on\r\n"); - } - - } else { - if (config.ap_on) { - wifi_set_opmode(STATION_MODE); -#ifdef MDNS - if (config.mdns_mode == 2) { - espconn_mdns_close(); - } -#endif - config.ap_on = false; - os_sprintf(response, "AP off\r\n"); - } else { - os_sprintf(response, "AP already off\r\n"); - } - } - goto command_handled; - } - - if (strcmp(tokens[1], "speed") == 0) { - uint16_t speed = atoi(tokens[2]); - bool succ = system_update_cpu_freq(speed); - if (succ) - config.clock_speed = speed; - os_sprintf(response, "Clock speed update %s\r\n", succ ? "successful" : "failed"); - goto command_handled; - } - - if (strcmp(tokens[1],"bitrate") == 0) - { - config.bit_rate = atoi(tokens[2]); - os_sprintf(response, "Bitrate set to %d\r\n", config.bit_rate); - goto command_handled; - } - - if (strcmp(tokens[1],"system_output") == 0) - { - config.system_output = atoi(tokens[2]); - os_sprintf(response, "System output %s\r\n", config.system_output?"on":"off"); - goto command_handled; - } - - if (strcmp(tokens[1], "network") == 0) { - config.network_addr.addr = ipaddr_addr(tokens[2]); - ip4_addr4(&config.network_addr) = 0; - os_sprintf(response, "Network set to %d.%d.%d.%d\r\n", IP2STR(&config.network_addr)); - goto command_handled; - } - - if (strcmp(tokens[1], "dns") == 0) { - if (os_strcmp(tokens[2], "dhcp") == 0) { - config.dns_addr.addr = 0; - os_sprintf(response, "DNS from DHCP\r\n"); - } else { - config.dns_addr.addr = ipaddr_addr(tokens[2]); - os_sprintf(response, "DNS set to %d.%d.%d.%d\r\n", IP2STR(&config.dns_addr)); - if (config.dns_addr.addr) { - dns_ip.addr = config.dns_addr.addr; - } - } - goto command_handled; - } - - if (strcmp(tokens[1], "ip") == 0) { - if (os_strcmp(tokens[2], "dhcp") == 0) { - config.my_addr.addr = 0; - os_sprintf(response, "IP from DHCP\r\n"); - } else { - config.my_addr.addr = ipaddr_addr(tokens[2]); - os_sprintf(response, "IP address set to %d.%d.%d.%d\r\n", IP2STR(&config.my_addr)); - } - goto command_handled; - } - - if (strcmp(tokens[1], "netmask") == 0) { - config.my_netmask.addr = ipaddr_addr(tokens[2]); - os_sprintf(response, "IP netmask set to %d.%d.%d.%d\r\n", IP2STR(&config.my_netmask)); - goto command_handled; - } - - if (strcmp(tokens[1], "gw") == 0) { - config.my_gw.addr = ipaddr_addr(tokens[2]); - os_sprintf(response, "Gateway set to %d.%d.%d.%d\r\n", IP2STR(&config.my_gw)); - goto command_handled; - } -#ifdef MDNS - if (strcmp(tokens[1], "mdns_mode") == 0) { - config.mdns_mode = atoi(tokens[2]); - os_sprintf(response, "mDNS mode set to %d\r\n", config.mdns_mode); - goto command_handled; - } -#endif -#ifdef REMOTE_CONFIG - if (strcmp(tokens[1], "config_port") == 0) { - config.config_port = atoi(tokens[2]); - if (config.config_port == 0) - os_sprintf(response, "WARNING: if you save this, remote console access will be disabled!\r\n"); - else - os_sprintf(response, "Config port set to %d\r\n", config.config_port); - goto command_handled; - } - - if (strcmp(tokens[1], "config_access") == 0) { - config.config_access = atoi(tokens[2]) & (LOCAL_ACCESS | REMOTE_ACCESS); - if (config.config_access == 0) - os_sprintf(response, "WARNING: if you save this, remote console access will be disabled!\r\n"); - else - os_sprintf(response, "Config access set\r\n"); - goto command_handled; - } -#endif - if (strcmp(tokens[1], "broker_subscriptions") == 0) { - config.max_subscriptions = atoi(tokens[2]); - os_sprintf(response, "Broker subscriptions set\r\n"); - goto command_handled; - } - - if (strcmp(tokens[1], "broker_retained_messages") == 0) { - config.max_retained_messages = atoi(tokens[2]); - os_sprintf(response, "Broker retained messages set\r\n"); - goto command_handled; - } - - if (strcmp(tokens[1], "broker_clients") == 0) { - config.max_clients = atoi(tokens[2]); - os_sprintf(response, "Broker max clients set\r\n"); - goto command_handled; - } - - if (strcmp(tokens[1], "broker_user") == 0) { - os_strncpy(config.mqtt_broker_user, tokens[2], 32); - config.mqtt_broker_user[31] = '\0'; - os_sprintf(response, "Broker username set\r\n"); - goto command_handled; - } - - if (strcmp(tokens[1], "broker_password") == 0) { - if (os_strcmp(tokens[2], "none") == 0) { - config.mqtt_broker_password[0] = '\0'; - } else { - os_strncpy(config.mqtt_broker_password, tokens[2], 32); - config.mqtt_broker_password[31] = '\0'; - } - os_sprintf(response, "Broker password set\r\n"); - goto command_handled; - } - - if (strcmp(tokens[1], "broker_access") == 0) { - config.mqtt_broker_access = atoi(tokens[2]) & (LOCAL_ACCESS | REMOTE_ACCESS); - os_sprintf(response, "Broker access set\r\n", config.config_port); - goto command_handled; - } - - if (strcmp(tokens[1], "broker_autoretain") == 0) { - config.auto_retained = atoi(tokens[2]) != 0; - os_sprintf(response, "Broker autoretain set\r\n", config.config_port); - goto command_handled; - } -#ifdef SCRIPTED - if (strcmp(tokens[1], "script_logging") == 0) { - lang_logging = atoi(tokens[2]); - os_sprintf(response, "Script logging set\r\n"); - goto command_handled; - } - - if (tokens[1][0] == '@') { - uint32_t slot_no = atoi(&tokens[1][1]); - if (slot_no == 0 || slot_no > MAX_FLASH_SLOTS) { - os_sprintf(response, "Invalid flash slot number"); - } else { - slot_no--; - uint8_t slots[MAX_FLASH_SLOTS*FLASH_SLOT_LEN]; - blob_load(VARS_SLOT, (uint32_t *)slots, sizeof(slots)); - os_strcpy(&slots[slot_no*FLASH_SLOT_LEN], tokens[2]); - blob_save(VARS_SLOT, (uint32_t *)slots, sizeof(slots)); - os_sprintf(response, "%s written to flash\r\n", tokens[1]); - } - goto command_handled; - } -#ifdef GPIO -#ifdef GPIO_PWM - if (strcmp(tokens[1], "pwm_period") == 0) { - config.pwm_period = atoi(tokens[2]); - os_sprintf(response, "PWM period set\r\n"); - goto command_handled; - } -#endif -#endif -#endif -#ifdef NTP - if (strcmp(tokens[1], "ntp_server") == 0) { - os_strncpy(config.ntp_server, tokens[2], 32); - config.ntp_server[31] = 0; - ntp_set_server(config.ntp_server); - os_sprintf(response, "NTP server set to %s\r\n", config.ntp_server); - goto command_handled; - } - - if (strcmp(tokens[1], "ntp_interval") == 0) { - config.ntp_interval = atoi(tokens[2]) * 1000000; - os_sprintf(response, "NTP interval set to %d s\r\n", atoi(tokens[2])); - goto command_handled; - } - - if (strcmp(tokens[1], "ntp_timezone") == 0) { - config.ntp_timezone = atoi(tokens[2]); - set_timezone(config.ntp_timezone); - os_sprintf(response, "NTP timezone set to %d h\r\n", config.ntp_timezone); - goto command_handled; - } -#endif -#ifdef MQTT_CLIENT - if (strcmp(tokens[1], "mqtt_host") == 0) { - os_strncpy(config.mqtt_host, tokens[2], 32); - config.mqtt_host[31] = 0; - os_sprintf(response, "MQTT host set\r\n"); - goto command_handled; - } - - if (strcmp(tokens[1], "mqtt_port") == 0) { - config.mqtt_port = atoi(tokens[2]); - os_sprintf(response, "MQTT port set\r\n"); - goto command_handled; - } - - if (strcmp(tokens[1], "mqtt_ssl") == 0) { - config.mqtt_ssl = atoi(tokens[2]); - os_sprintf(response, "MQTT ssl %s\r\n", config.mqtt_ssl?"on":"off"); - goto command_handled; - } - - if (strcmp(tokens[1], "mqtt_user") == 0) { - os_strncpy(config.mqtt_user, tokens[2], 32); - config.mqtt_user[31] = 0; - os_sprintf(response, "MQTT user set\r\n"); - goto command_handled; - } - - if (strcmp(tokens[1], "mqtt_password") == 0) { - os_strncpy(config.mqtt_password, tokens[2], 32); - config.mqtt_password[31] = 0; - os_sprintf(response, "MQTT password set\r\n"); - goto command_handled; - } - - if (strcmp(tokens[1], "mqtt_id") == 0) { - os_strncpy(config.mqtt_id, tokens[2], 32); - config.mqtt_id[31] = 0; - os_sprintf(response, "MQTT id set\r\n"); - goto command_handled; - } -#endif /* MQTT_CLIENT */ - } - - } - - /* Control comes here only if the tokens[0] command is not handled */ - os_sprintf(response, "\r\nInvalid Command\r\n"); - - command_handled: - to_console(response); - command_handled_2: - system_os_post(user_procTaskPrio, SIG_CONSOLE_TX, (ETSParam) pespconn); - return; -} - #ifdef SCRIPTED void ICACHE_FLASH_ATTR do_command(char *t1, char *t2, char *t3) { ringbuf_memcpy_into(console_rx_buffer, t1, os_strlen(t1));