diff --git a/platformio_override.ini b/platformio_override.ini index f113692a5dc4..0c45c1e8dff8 100644 --- a/platformio_override.ini +++ b/platformio_override.ini @@ -60,7 +60,7 @@ build_flags = ${core.build_flags} ; Build variant 2MB = 1MB firmware, 1MB filesystem (most Shelly devices) ;board = esp8266_2M1M ; Build variant 4MB = 1MB firmware, 1MB OTA, 2MB filesystem (WEMOS D1 Mini, NodeMCU, Sonoff POW) -;board = esp8266_4M2M +board = esp8266_4M2M ; set CPU frequency to 80MHz (default) or 160MHz ;board_build.f_cpu = 160000000L @@ -71,7 +71,7 @@ build_flags = ${core.build_flags} ;board_build.f_flash = 80000000L ; *** Upload Serial reset method for Wemos and NodeMCU -upload_port = /dev/tty.usbserial-1420 +upload_port = /dev/tty.usbserial-14110 extra_scripts = ${scripts_defaults.extra_scripts} ; pio-tools/obj-dump.py diff --git a/tasmota/i18n.h b/tasmota/i18n.h index c5922dd7d6d3..382c7ba48011 100644 --- a/tasmota/i18n.h +++ b/tasmota/i18n.h @@ -354,6 +354,10 @@ #define D_CMND_HUMOFFSET "HumOffset" #define D_CMND_GLOBAL_TEMP "GlobalTemp" #define D_CMND_GLOBAL_HUM "GlobalHum" +#define D_CMND_FACTORY_RESET "FactoryReset" +#define D_CMND_SSID_RESET "SSIDReset" +#define D_CMND_UPDATE_CERT "UpdateCert" +#define D_CMND_READ_INPUT "ReadInput" #ifdef ESP32 #define D_CMND_TOUCH_CAL "TouchCal" diff --git a/tasmota/language/ko_KO.h b/tasmota/language/ko_KO.h index 90e3e35936bc..698f76ccfbee 100644 --- a/tasmota/language/ko_KO.h +++ b/tasmota/language/ko_KO.h @@ -302,7 +302,7 @@ #define D_SELECT_YOUR_WIFI_NETWORK "아래에서 WiFi를 선택하세요" #define D_SHOW_MORE_WIFI_NETWORKS "다른 WiFi 탐색" #define D_SHOW_MORE_OPTIONS "더보기" -#define D_CHECK_CREDENTIALS "Please, check your credentials" +#define D_CHECK_CREDENTIALS "올바른 WiFi 네트워크인지 확인해주세요" #define D_SUCCESSFUL_WIFI_CONNECTION "Successful WiFi Connection" #define D_NOW_YOU_CAN_CLOSE_THIS_WINDOW "Now you can close this window" #define D_REDIRECTING_TO_NEW_IP "새로운 네트워크로 이동 중입니다. 잠시만 기다려주세요" @@ -393,6 +393,8 @@ #define D_ENABLE_WEBLOG_FOR_RESPONSE "응답이 있다면 Weblog 2를 사용" #define D_NEED_USER_AND_PASSWORD "user=<아이디>&password=<비밀번호> 필요" +#define D_CHECK_CERTIFICATION "인증서 정보가 없습니다. 직방 앱을 사용해 기기를 등록해주세요." + // xdrv_01_mqtt.ino #define D_FINGERPRINT "TLS 지문 확인..." #define D_TLS_CONNECT_FAILED_TO "TLS 연결 실패" diff --git a/tasmota/settings.h b/tasmota/settings.h index 075759b716b3..7a9a50367de4 100644 --- a/tasmota/settings.h +++ b/tasmota/settings.h @@ -436,7 +436,7 @@ typedef union { } DisplayOptions; const uint32_t settings_text_size = 699; // Settings->text_pool[size] = Settings->display_model (2D2) - Settings->text_pool (017) -const uint8_t MAX_TUYA_FUNCTIONS = 16; +const uint8_t MAX_TUYA_FUNCTIONS = 1; typedef struct { uint16_t cfg_holder; // 000 v6 header @@ -689,7 +689,6 @@ typedef struct { uint16_t syslog_port; // ECA uint8_t syslog_level; // ECC uint8_t webserver; // ECD - uint8_t weblog_level; // ECE uint8_t mqtt_fingerprint[2][20]; // ECF uint8_t ex_adc_param_type; // EF7 Free since 9.0.0.1 diff --git a/tasmota/settings.ino b/tasmota/settings.ino index 5569f2debf37..2820c6ba1d86 100644 --- a/tasmota/settings.ino +++ b/tasmota/settings.ino @@ -877,8 +877,6 @@ void SettingsDefaultSet2(void) { flag3.gui_hostname_ip |= GUI_SHOW_HOSTNAME; flag3.mdns_enabled |= MDNS_ENABLED; Settings->webserver = WEB_SERVER; - Settings->weblog_level = WEB_LOG_LEVEL; - SettingsUpdateText(SET_WEBPWD, PSTR(WEB_PASSWORD)); SettingsUpdateText(SET_CORS, PSTR(CORS_DOMAIN)); // Button diff --git a/tasmota/support.ino b/tasmota/support.ino index 16852a5657bf..5c513a232b16 100644 --- a/tasmota/support.ino +++ b/tasmota/support.ino @@ -2360,8 +2360,7 @@ void AddLogData(uint32_t loglevel, const char* log_data, const char* log_data_pa if (!TasmotaGlobal.log_buffer) { return; } // Leave now if there is no buffer available - uint32_t highest_loglevel = Settings->weblog_level; - if (Settings->mqttlog_level > highest_loglevel) { highest_loglevel = Settings->mqttlog_level; } + uint32_t highest_loglevel = Settings->mqttlog_level; if (TasmotaGlobal.syslog_level > highest_loglevel) { highest_loglevel = TasmotaGlobal.syslog_level; } if (TasmotaGlobal.templog_level > highest_loglevel) { highest_loglevel = TasmotaGlobal.templog_level; } if (TasmotaGlobal.uptime < 3) { highest_loglevel = LOG_LEVEL_DEBUG_MORE; } // Log all before setup correct log level diff --git a/tasmota/support_command.ino b/tasmota/support_command.ino index 0fa0370d664b..d8cc65260d00 100644 --- a/tasmota/support_command.ino +++ b/tasmota/support_command.ino @@ -39,6 +39,7 @@ const char kTasmotaCommands[] PROGMEM = "|" // No prefix #endif // USE_DEVICE_GROUPS_SEND D_CMND_DEVGROUP_SHARE "|" D_CMND_DEVGROUPSTATUS "|" D_CMND_DEVGROUP_TIE "|" #endif // USE_DEVICE_GROUPS + D_CMND_FACTORY_RESET "|" D_CMND_SSID_RESET "|" D_CMND_UPDATE_CERT "|" D_CMND_READ_INPUT "|" D_CMND_SENSOR "|" D_CMND_DRIVER #ifdef ESP32 "|Info|" D_CMND_TOUCH_CAL "|" D_CMND_TOUCH_THRES "|" D_CMND_TOUCH_NUM "|" D_CMND_CPU_FREQUENCY @@ -67,6 +68,7 @@ void (* const TasmotaCommand[])(void) PROGMEM = { #endif // USE_DEVICE_GROUPS_SEND &CmndDevGroupShare, &CmndDevGroupStatus, &CmndDevGroupTie, #endif // USE_DEVICE_GROUPS + &CmndFactoryReset, &CmndSSIDReset, &CmndUpdateCert, &CmndReadInput, &CmndSensor, &CmndDriver #ifdef ESP32 , &CmndInfo, &CmndTouchCal, &CmndTouchThres, &CmndTouchNum, &CmndCpuFrequency @@ -525,10 +527,10 @@ void CmndStatus(void) } if ((0 == payload) || (3 == payload)) { - Response_P(PSTR("{\"" D_CMND_STATUS D_STATUS3_LOGGING "\":{\"" D_CMND_SERIALLOG "\":%d,\"" D_CMND_WEBLOG "\":%d,\"" D_CMND_MQTTLOG "\":%d,\"" D_CMND_SYSLOG "\":%d,\"" + Response_P(PSTR("{\"" D_CMND_STATUS D_STATUS3_LOGGING "\":{\"" D_CMND_SERIALLOG "\":%d,\"" D_CMND_MQTTLOG "\":%d,\"" D_CMND_SYSLOG "\":%d,\"" D_CMND_LOGHOST "\":\"%s\",\"" D_CMND_LOGPORT "\":%d,\"" D_CMND_SSID "\":[\"%s\",\"%s\"],\"" D_CMND_TELEPERIOD "\":%d,\"" D_JSON_RESOLUTION "\":\"%08X\",\"" D_CMND_SETOPTION "\":[\"%08X\",\"%s\",\"%08X\",\"%08X\",\"%08X\"]}}"), - Settings->seriallog_level, Settings->weblog_level, Settings->mqttlog_level, Settings->syslog_level, + Settings->seriallog_level, Settings->mqttlog_level, Settings->syslog_level, SettingsText(SET_SYSLOG_HOST), Settings->syslog_port, EscapeJSONString(SettingsText(SET_STASSID1)).c_str(), EscapeJSONString(SettingsText(SET_STASSID2)).c_str(), Settings->tele_period, Settings->flag2.data, Settings->flag.data, ToHex_P((unsigned char*)Settings->param, PARAM8_SIZE, stemp2, sizeof(stemp2)), Settings->flag3.data, Settings->flag4.data, Settings->flag5.data); @@ -2263,6 +2265,62 @@ void CmndDevGroupTie(void) } #endif // USE_DEVICE_GROUPS +void CmndFactoryReset(void) +{ + TasmotaGlobal.restart_flag = 212; + Response_P(PSTR("{\"Factory reset\":\"Success\"}")); +} + +void CmndSSIDReset(void) +{ + SettingsUpdateText(SET_STASSID1, ""); + SettingsUpdateText(SET_STAPWD1, ""); + SettingsUpdateText(SET_STASSID2, ""); + SettingsUpdateText(SET_STAPWD2, ""); + TasmotaGlobal.restart_flag = 2; + Response_P(PSTR("{\"SSID reset\":\"Success\"}")); +} + +void CmndUpdateCert(void) +{ + if (XdrvMailbox.data_len > 0) { + JsonParser parser((char*) XdrvMailbox.data); + JsonParserObject stateObject = parser.getRootObject(); + + String cert = stateObject["cert"].getStr(); + String key = stateObject["key"].getStr(); + + if (!cert.length() || !key.length()) { + Response_P(PSTR("{\"Cert update\":\"Failed\"}")); + return; + } + + TasmotaGlobal.cert_info_flag = 0; + char* certCharType = (char*)cert.c_str(); + char* keyCharType = (char*)key.c_str(); + + memcpy(AmazonClientCert, certCharType, strlen(certCharType)); + memcpy(AmazonPrivateKey, keyCharType, strlen(keyCharType)); + printf("cert: %s\n", certCharType); + printf("key: %s\n", keyCharType); + + cert.~String(); + key.~String(); + + ConvertTlsFile(0); + ConvertTlsFile(1); + TasmotaGlobal.cert_info_flag = 1; + Response_P(PSTR("{\"Cert update\":\"Success\"}")); + } else { + Response_P(PSTR("{\"Cert update\":\"Failed\"}")); + } +} + +void CmndReadInput(void) +{ + // TODO: Read GPIO value +} + void CmndSensor(void) { XsnsCall(FUNC_COMMAND_SENSOR); diff --git a/tasmota/support_tasmota.ino b/tasmota/support_tasmota.ino index 80d41aef8ccf..b2b3ae94f0b7 100644 --- a/tasmota/support_tasmota.ino +++ b/tasmota/support_tasmota.ino @@ -1087,7 +1087,7 @@ void Every250mSeconds(void) switch (TasmotaGlobal.state_250mS) { case 0: // Every x.0 second - if (TasmotaGlobal.ota_state_flag && CommandsReady()) { + if (TasmotaGlobal.ota_state_flag && CommandsReady()) { // TODO: Flash에 저장된 OTA 설정 값을 읽는 것으로 변경, OTA 모드, 프로비저닝 모드에서 동작하지 않도록 체크 로직 필요 TasmotaGlobal.ota_state_flag--; if (2 == TasmotaGlobal.ota_state_flag) { RtcSettings.ota_loader = 0; // Try requested image first @@ -1312,22 +1312,9 @@ void Every250mSeconds(void) StartMdns(); #ifdef USE_WEBSERVER - if (Settings->webserver) { - -#ifdef ESP8266 - if (!WifiIsInManagerMode()) { StartWebserver(Settings->webserver, WiFi.localIP()); } -#endif // ESP8266 -#ifdef ESP32 -#ifdef USE_ETHERNET - StartWebserver(Settings->webserver, (EthernetLocalIP()) ? EthernetLocalIP() : WiFi.localIP()); -#else - StartWebserver(Settings->webserver, WiFi.localIP()); -#endif -#endif // ESP32 - - MdnsAddServiceHttp(); - } else { + if (!Settings->webserver) { StopWebserver(); + StopWebserverSecure(); } #ifdef USE_EMULATION if (Settings->flag2.emulation) { UdpConnect(); } @@ -1345,7 +1332,12 @@ void Every250mSeconds(void) } #endif // USE_KNX - MqttCheck(); + if (TasmotaGlobal.idToken_info_flag) { + // 프로비저닝 모드 + ProvisioningCheck(); + } else { + MqttCheck(); + } } else { #ifdef USE_EMULATION UdpDisconnect(); @@ -1378,9 +1370,6 @@ void ArduinoOTAInit(void) { ArduinoOTA.setPort(8266); ArduinoOTA.setHostname(NetworkHostname()); - if (strlen(SettingsText(SET_WEBPWD))) { - ArduinoOTA.setPassword(SettingsText(SET_WEBPWD)); - } ArduinoOTA.onStart([]() { diff --git a/tasmota/tasmota.h b/tasmota/tasmota.h index 1d2a92d547cc..8b82aaace9e8 100644 --- a/tasmota/tasmota.h +++ b/tasmota/tasmota.h @@ -64,10 +64,10 @@ const uint8_t MAX_PWMS = 5; // Max number of PWM channels const uint8_t MAX_COUNTERS = 4; // Max number of counter sensors const uint8_t MAX_TIMERS = 16; // Max number of Timers const uint8_t MAX_PULSETIMERS = 8; // Max number of supported pulse timers -const uint8_t MAX_DOMOTICZ_IDX = 4; // Max number of Domoticz device, key and switch indices -const uint8_t MAX_DOMOTICZ_SNS_IDX = 12; // Max number of Domoticz sensors indices -const uint8_t MAX_KNX_GA = 10; // Max number of KNX Group Addresses to read that can be set -const uint8_t MAX_KNX_CB = 10; // Max number of KNX Group Addresses to write that can be set +const uint8_t MAX_DOMOTICZ_IDX = 1; // Max number of Domoticz device, key and switch indices +const uint8_t MAX_DOMOTICZ_SNS_IDX = 1; // Max number of Domoticz sensors indices +const uint8_t MAX_KNX_GA = 1; // Max number of KNX Group Addresses to read that can be set +const uint8_t MAX_KNX_CB = 1; // Max number of KNX Group Addresses to write that can be set const uint8_t MAX_XNRG_DRIVERS = 32; // Max number of allowed energy drivers const uint8_t MAX_XDSP_DRIVERS = 32; // Max number of allowed display drivers const uint8_t MAX_XDRV_DRIVERS = 96; // Max number of allowed driver drivers @@ -78,7 +78,7 @@ const uint8_t MAX_SHUTTER_RELAYS = 8; // Max number of shutter relays const uint8_t MAX_SHUTTER_KEYS = 4; // Max number of shutter keys or buttons const uint8_t MAX_PCF8574 = 4; // Max number of PCF8574 devices const uint8_t MAX_RULE_SETS = 3; // Max number of rule sets of size 512 characters -const uint16_t MAX_RULE_SIZE = 512; // Max number of characters in rules +const uint16_t MAX_RULE_SIZE = 1; // Max number of characters in rules const uint16_t VL53L0X_MAX_SENSORS = 8; // Max number of VL53L0X sensors #ifdef ESP32 @@ -123,6 +123,8 @@ const char WIFI_HOSTNAME[] = "ZIGBANG"; // Expands to -50 code) + #undef USE_APDS9960_COLOR // Enable APDS9960 Color feature (+0.8k code) + #undef USE_APDS9960_STARTMODE // Default to enable Gesture mode + #undef USE_ADE7953 // [I2cDriver7] Enable ADE7953 Energy monitor as used on Shelly 2.5 (I2C address 0x38) (+1k5) + +// -- SPI sensors --------------------------------- + #undef USE_MIBLE // BLE-bridge for some Mijia-BLE-sensors (+4k7 code) + #undef USE_DISPLAY_ILI9341 // [DisplayModel 4] Enable ILI9341 Tft 480x320 display (+19k code) + +// -- Power monitoring sensors -------------------- +#undef USE_ENERGY_SENSOR // Add support for Energy Monitors (+14k code) +#undef USE_ENERGY_MARGIN_DETECTION // Add support for Energy Margin detection (+1k6 code) + #undef USE_ENERGY_POWER_LIMIT // Add additional support for Energy Power Limit detection (+1k2 code) +#undef USE_ENERGY_DUMMY // Add support for dummy Energy monitor allowing user values (+0k7 code) +#undef USE_HLW8012 // Add support for HLW8012, BL0937 or HJL-01 Energy Monitor for Sonoff Pow and WolfBlitz +#undef USE_CSE7766 // Add support for CSE7766 Energy Monitor for Sonoff S31 and Pow R2 +#undef USE_PZEM004T // Add support for PZEM004T Energy monitor (+2k code) +#undef USE_PZEM_AC // Add support for PZEM014,016 Energy monitor (+1k1 code) +#undef USE_PZEM_DC // Add support for PZEM003,017 Energy monitor (+1k1 code) +#undef USE_MCP39F501 // Add support for MCP39F501 Energy monitor as used in Shelly 2 (+3k1 code) + #undef SDM72_SPEED // SDM72-Modbus RS485 serial speed (default: 9600 baud) + #undef SDM120_SPEED // SDM120-Modbus RS485 serial speed (default: 2400 baud) + #undef SDM630_SPEED // SDM630-Modbus RS485 serial speed (default: 9600 baud) + #undef DDS2382_SPEED // Hiking DDS2382 Modbus RS485 serial speed (default: 9600 baud) + #undef DDSU666_SPEED // Chint DDSU666 Modbus RS485 serial speed (default: 9600 baud) + #undef SOLAXX1_SPEED // Solax X1 Modbus RS485 serial speed (default: 9600 baud) + #undef SOLAXX1_PV2 // Solax X1 using second PV + #undef LE01MR_SPEED // LE-01MR modbus baudrate (default: 9600) + #undef LE01MR_ADDR // LE-01MR modbus address (default: 0x01) +#undef USE_BL0940 // Add support for BL0940 Energy monitor as used in Blitzwolf SHP-10 (+1k6 code) + #undef IEM3000_SPEED // iEM3000-Modbus RS485 serial speed (default: 19200 baud) + #undef IEM3000_ADDR // iEM3000-Modbus modbus address (default: 0x01) + +// -- Low level interface devices ----------------- +#undef USE_DHT // Add support for DHT11, AM2301 (DHT21, DHT22, AM2302, AM2321) and SI7021 Temperature and Humidity sensor (1k6 code) + #undef MAX31865_PTD_WIRES // PTDs come in several flavors, pick yours. Specific settings per sensor possible with MAX31865_PTD_WIRES1..MAX31865_PTD_WIRES6 + #undef MAX31865_PTD_RES // Nominal PTD resistance at 0°C (100Ω for a PT100, 1000Ω for a PT1000, YMMV!). Specific settings per sensor possible with MAX31865_PTD_RES1..MAX31865_PTD_RES6 + #undef MAX31865_REF_RES // Reference resistor (Usually 430Ω for a PT100, 4300Ω for a PT1000). Specific settings per sensor possible with MAX31865_REF_RES1..MAX31865_REF_RES6 + #undef MAX31865_PTD_BIAS // To calibrate your not-so-good PTD. Specific settings per sensor possible with MAX31865_PTD_BIAS1..MAX31865_PTD_BIAS6 + +// -- IR Remote features - subset of IR protocols -------------------------- +#undef USE_IR_REMOTE // Send IR remote commands using library IRremoteESP8266 and ArduinoJson (+4k3 code, 0k3 mem, 48 iram) + #undef IR_SEND_INVERTED // Invert the output. (default = false) e.g. LED is illuminated when GPIO is LOW rather than HIGH. + // Setting inverted to something other than the default could easily destroy your IR LED if you are overdriving it. + // Unless you REALLY know what you are doing, don't change this. + #undef IR_SEND_USE_MODULATION // Do we do frequency modulation during transmission? i.e. If not, assume a 100% duty cycle. + #undef USE_IR_SEND_NEC // Support IRsend NEC protocol + #undef USE_IR_SEND_RC5 // Support IRsend Philips RC5 protocol + #undef USE_IR_SEND_RC6 // Support IRsend Philips RC6 protocol + + #undef USE_IR_RECEIVE // Support for IR receiver (+7k2 code, 264 iram) + #undef IR_RCV_BUFFER_SIZE // Max number of packets allowed in capture buffer (default 100 (*2 bytes ram)) + #undef IR_RCV_TIMEOUT // Number of milli-Seconds of no-more-data before we consider a message ended (default 15) + #undef IR_RCV_MIN_UNKNOWN_SIZE // Set the smallest sized "UNKNOWN" message packets we actually care about (default 6, max 255) + #undef IR_RCV_WHILE_SENDING // Turns on receiver while sending messages, i.e. receive your own. This is unreliable and can cause IR timing issues + // -- HTTP GUI Colors ----------------------------- // HTML hex color codes. Only 3 and 6 digit hex string values are supported!! See https://www.w3schools.com/colors/colors_hex.asp // Light theme - pre v7 diff --git a/tasmota/xdrv_01_3_httpsClient.ino b/tasmota/xdrv_01_3_httpsClient.ino new file mode 100644 index 000000000000..fcf5928a61c4 --- /dev/null +++ b/tasmota/xdrv_01_3_httpsClient.ino @@ -0,0 +1,135 @@ +#include +#include + +// Use web browser to view and copy +// SHA1 fingerprint of the certificate +const char fingerprint[] PROGMEM = "e8 c3 8d d8 41 15 1b 6d a9 9c 26 36 29 30 b2 14 f7 71 0d 1c"; + +WiFiClientSecure client; +uint16_t provisioning_counter = 0; + +void HTTPSClientInit(void) { + client.setFingerprint(fingerprint); +} + +void GetCertification(void) { + const char host[] = "p2x2wtwvsf.execute-api.ap-northeast-2.amazonaws.com"; + String url = "/dev/certification?deviceType=DEV-TASMOTA-LIGHT&macAddr=" + NetworkUniqueId(); + + char* idToken = (char*)malloc(1024); + + bool load_result = TfsLoadFile("/idToken.txt", (uint8_t*)idToken, 1024); + + if (!load_result || !client.connect(host, 443)) { + AddLog(LOG_LEVEL_INFO, PSTR("%s에 연결 실패"), host); + } else { + AddLog(LOG_LEVEL_INFO, PSTR("%s에 연결 성공"), host); + + client.print(String("GET ") + url + " HTTP/1.1\r\n" + + "Host: " + host + "\r\n" + + "User-Agent: Zigbang\r\n" + + "Authorization: " + idToken +"\r\n" + + "Connection: close\r\n\r\n"); + + String headers = ""; + String body = ""; + bool finishedHeaders = false; + bool currentLineIsBlank = true; + bool gotResponse = false; + + free(idToken); + + unsigned long timeout = millis(); + while (!client.available()) { + if (millis() - timeout > 20000) { + printf("시간초과!\n"); + client.stop(); + provisioning_counter = 0; + return; + } + } + + while (client.available()) { + char c = client.read(); + + if (finishedHeaders) { + body = body + c; + } else { + if (currentLineIsBlank && c == '\n') { + finishedHeaders = true; + } else { + headers = headers + c; + } + } + + if (c == '\n') { + currentLineIsBlank = true; + } + else if (c != '\r') { + currentLineIsBlank = false; + } + + gotResponse = true; + } + if (gotResponse) { + if (headers.startsWith("HTTP/1.1 200")) { + AddLog(LOG_LEVEL_INFO, PSTR("요청 성공")); + JsonParser parser((char*) body.c_str()); + JsonParserObject stateObject = parser.getRootObject(); + + String cert = stateObject["cert"].getStr(); + String key = stateObject["key"].getStr(); + + if (!cert.length() || !key.length()) { + AddLog(LOG_LEVEL_INFO, PSTR("Cert 정보 Error")); + client.stop(); + provisioning_counter = 0; + return; + } + + char* certCharType = (char*)cert.c_str(); + char* keyCharType = (char*)key.c_str(); + + memcpy(AmazonClientCert, certCharType, strlen(certCharType)); + memcpy(AmazonPrivateKey, keyCharType, strlen(keyCharType)); + + url.~String(); + headers.~String(); + body.~String(); + cert.~String(); + key.~String(); + + if (!ConvertTlsFile(0) || !ConvertTlsFile(1)) { + AddLog(LOG_LEVEL_INFO, PSTR("Cert 저장 실패")); + client.stop(); + provisioning_counter = 0; + return; + } + + SettingsUpdateText(SET_ID_TOKEN, ""); + TasmotaGlobal.idToken_info_flag = 0; + TasmotaGlobal.cert_info_flag = 1; + TasmotaGlobal.restart_flag = 2; + AddLog(LOG_LEVEL_INFO, PSTR("Cert 저장 성공")); + } else { + AddLog(LOG_LEVEL_INFO, PSTR("요청 실패")); + } + + client.stop(); + provisioning_counter = 0; + return; + } + } +} + +void ProvisioningCheck(void) { + if (!TasmotaGlobal.idToken_info_flag && TasmotaGlobal.cert_info_flag) { + return; + } else { + provisioning_counter++; + if (provisioning_counter == 5) { + TasmotaGlobal.restart_flag = 2; + } + GetCertification(); + } +} \ No newline at end of file diff --git a/tasmota/xdrv_01_webserver.ino b/tasmota/xdrv_01_webserver.ino index de759fe99d89..f0b59f0788b5 100644 --- a/tasmota/xdrv_01_webserver.ino +++ b/tasmota/xdrv_01_webserver.ino @@ -60,6 +60,8 @@ const uint16_t HTTP_OTA_RESTART_RECONNECT_TIME = 10000; // milliseconds - Allow #include #include +#include +#include const char HTTP_SCRIPT_ROOT2[] PROGMEM = "var rfsh=1,ft;" @@ -183,63 +185,6 @@ const char HTTP_SCRIPT_RELOAD_TIME[] PROGMEM = #include "./html_uncompressed/HTTP_SCRIPT_CONSOL.h" #endif -const char HTTP_MODULE_TEMPLATE_REPLACE_INDEX[] PROGMEM = - "}2%d'>%s (%d)}3"; // }2 and }3 are used in below os.replace -const char HTTP_MODULE_TEMPLATE_REPLACE_NO_INDEX[] PROGMEM = - "}2%d'>%s}3"; // }2 and }3 are used in below os.replace - -#ifdef USE_UNISHOX_COMPRESSION - #include "./html_compressed/HTTP_SCRIPT_MODULE_TEMPLATE.h" - #include "./html_compressed/HTTP_SCRIPT_TEMPLATE.h" -#else - #include "./html_uncompressed/HTTP_SCRIPT_MODULE_TEMPLATE.h" - #include "./html_uncompressed/HTTP_SCRIPT_TEMPLATE.h" -#endif - -#if defined(ESP32) && CONFIG_IDF_TARGET_ESP32C3 -const char HTTP_SCRIPT_TEMPLATE2[] PROGMEM = - "for(i=0;i<" STR(MAX_USER_PINS) ";i++){" - "sk(g[i],i);" // Set GPIO - "}"; -#else // Now ESP32 and ESP8266 -const char HTTP_SCRIPT_TEMPLATE2[] PROGMEM = - "j=0;" - "for(i=0;i<" STR(MAX_USER_PINS) ";i++){" // Supports 13 GPIOs - "if(6==i){j=9;}" - "if(8==i){j=12;}" - "sk(g[i],j);" // Set GPIO - "j++;" - "}"; -#endif -const char HTTP_SCRIPT_TEMPLATE3[] PROGMEM = - "\";" - "sk(g[13]," STR(ADC0_PIN) ");"; // Set ADC0 - -const char HTTP_SCRIPT_TEMPLATE4[] PROGMEM = - "g=o.shift();" // FLAG - "for(i=0;i<" STR(GPIO_FLAG_USED) ";i++){" - "p=(g>>i)&1;" - "eb('c'+i).checked=p;" // Set FLAG checkboxes - "}" - "if(" STR(USER_MODULE) "==c){" - "g=o.shift();" - "eb('g99').value=g;" // Set BASE for initial select - "}" - "}" - "function st(t){" - "c=t;" // Needed for initial BASE select - "var a='tp?t='+t;" - "ld(a,x1);" // ?t related to WebGetArg("t", stemp, sizeof(stemp)); - "}" - "function sl(){" - "os=\""; // }2'0'>Sonoff Basic (1)}3... -const char HTTP_SCRIPT_TEMPLATE5[] PROGMEM = - "\";" - "sk(" STR(WEMOS_MODULE) ",99);" // 17 = WEMOS - "st(" STR(USER_MODULE) ");" - "}" - "wl(sl);"; - const char HTTP_SCRIPT_INFO_BEGIN[] PROGMEM = "function i(){" "var s,o=\""; @@ -328,21 +273,6 @@ const char HTTP_FORM_LOGIN[] PROGMEM = "" ""; -const char HTTP_FORM_TEMPLATE[] PROGMEM = - "
 " D_TEMPLATE_PARAMETERS " " - "
"; -const char HTTP_FORM_TEMPLATE_FLAG[] PROGMEM = - "

" // Keep close so do not use
- "
 " D_TEMPLATE_FLAGS " 

" -// "
" - "

"; - -const char HTTP_FORM_MODULE[] PROGMEM = - "
 " D_MODULE_PARAMETERS " " - "" - "

" D_MODULE_TYPE " (%s)

" - "
"; - const char HTTP_FORM_WIFI_PART1[] PROGMEM = "
 " D_WIFI_PARAMETERS " " "" @@ -356,30 +286,6 @@ const char HTTP_FORM_WIFI_PART2[] PROGMEM = "

" D_HOSTNAME " (%s)

" "

" D_CORS_DOMAIN "

"; -const char HTTP_FORM_LOG1[] PROGMEM = - "
 " D_LOGGING_PARAMETERS " " - ""; -const char HTTP_FORM_LOG2[] PROGMEM = - "

" D_SYSLOG_HOST " (" SYS_LOG_HOST ")

" - "

" D_SYSLOG_PORT " (" STR(SYS_LOG_PORT) ")

" - "

" D_TELEMETRY_PERIOD " (" STR(TELE_PERIOD) ")

"; - -const char HTTP_FORM_OTHER[] PROGMEM = - "
 " D_OTHER_PARAMETERS " " - "" - "

" - "
 " D_TEMPLATE " " - "

" // We need ' apostrophe here as the template contains " quotation mark - "

" - "
" - "
" - "

" - "
" - "
" - "
" - "

" - "
"; - const char HTTP_FORM_END[] PROGMEM = "
" "" @@ -427,27 +333,21 @@ const char HTTP_DEVICE_STATE[] PROGMEM = "
on(F("/info"), HTTP_GET, HandleDeviceInfo); - Webserver->on(F("/certs"), HTTP_GET, HandleCertsInfo); - Webserver->on(F("/certs"), HTTP_POST, HandleCertsConfiguration); Webserver->on(F("/frt"), HTTP_GET, HandleFactoryResetConfiguration); Webserver->onNotFound(HandleNotFound); // Webserver->on(F("/u2"), HTTP_POST, HandleUploadDone, HandleUploadLoop); // this call requires 2 functions so we keep a direct call @@ -611,7 +513,6 @@ void StartWebserver(int type, IPAddress ipweb) XsnsCall(FUNC_WEB_ADD_HANDLER); #endif // Not FIRMWARE_MINIMAL } - Web.reset_web_log_flag = false; Webserver->begin(); // Web server start } @@ -672,38 +573,18 @@ void WifiManagerBegin(bool reset_only) DnsServer->start(DNS_PORT, "*", WiFi.softAPIP()); StartWebserver((reset_only ? HTTP_MANAGER_RESET_ONLY : HTTP_MANAGER), WiFi.softAPIP()); + StartWebserverSecure(); } void PollDnsWebserver(void) { if (DnsServer) { DnsServer->processNextRequest(); } if (Webserver) { Webserver->handleClient(); } + if (WebserverSecure) { WebserverSecure->handleClient(); } } /*********************************************************************************************/ -bool WebAuthenticate(void) -{ - if (strlen(SettingsText(SET_WEBPWD)) && (HTTP_MANAGER_RESET_ONLY != Web.state)) { - return Webserver->authenticate(WEB_USERNAME, SettingsText(SET_WEBPWD)); - } else { - return true; - } -} - -bool HttpCheckPriviledgedAccess(bool autorequestauth = true) -{ - if (HTTP_USER == Web.state) { - HandleRoot(); - return false; - } - if (autorequestauth && !WebAuthenticate()) { - Webserver->requestAuthentication(); - return false; - } - return true; -} - void HttpHeaderCors(void) { if (strlen(SettingsText(SET_CORS))) { @@ -818,10 +699,6 @@ void WSContentSend_PD(const char* formatP, ...) { // Content send snprintf_P ch void WSContentStart_P(const char* title, bool auth) { - if (auth && !WebAuthenticate()) { - return Webserver->requestAuthentication(); - } - WSContentBegin(200, CT_HTML); if (title != nullptr) { @@ -845,7 +722,7 @@ void WSContentSendStyle_P(const char* formatP, ...) WSContentSend_P(HTTP_HEAD_LAST_SCRIPT); WSContentSend_P(HTTP_HEAD_STYLE1, WebColor(COL_FORM), WebColor(COL_INPUT), WebColor(COL_INPUT_TEXT), WebColor(COL_INPUT), - WebColor(COL_INPUT_TEXT), WebColor(COL_CONSOLE), WebColor(COL_CONSOLE_TEXT), WebColor(COL_BACKGROUND)); + WebColor(COL_INPUT_TEXT), PSTR(""), PSTR(""), WebColor(COL_BACKGROUND)); WSContentSend_P(HTTP_HEAD_STYLE2, WebColor(COL_BUTTON), WebColor(COL_BUTTON_TEXT), WebColor(COL_BUTTON_HOVER), WebColor(COL_BUTTON_RESET), WebColor(COL_BUTTON_RESET_HOVER), WebColor(COL_BUTTON_SAVE), WebColor(COL_BUTTON_SAVE_HOVER), WebColor(COL_BUTTON)); @@ -1023,35 +900,6 @@ void WebRestart(uint32_t type) /*********************************************************************************************/ -void HandleWifiLogin(void) -{ - WSContentStart_P(PSTR(D_CONFIGURE_WIFI), false); // false means show page no matter if the client has or has not credentials - WSContentSendStyle(); - WSContentSend_P(HTTP_FORM_LOGIN); - - if (HTTP_MANAGER_RESET_ONLY == Web.state) { - WSContentSpaceButton(BUTTON_RESTART); -#ifndef FIRMWARE_MINIMAL - WSContentSpaceButton(BUTTON_RESET_CONFIGURATION); -#endif // FIRMWARE_MINIMAL - } - - WSContentStop(); -} - -uint32_t WebUseManagementSubmenu(void) { - static uint32_t management_count = 0; - - if (!management_count) { - XdrvMailbox.index = 1; - XdrvCall(FUNC_WEB_ADD_CONSOLE_BUTTON); - XsnsCall(FUNC_WEB_ADD_CONSOLE_BUTTON); - XdrvCall(FUNC_WEB_ADD_MANAGEMENT_BUTTON); - management_count = XdrvMailbox.index; - } - return management_count -1; -} - uint32_t WebDeviceColumns(void) { const uint32_t max_columns = 8; @@ -1116,8 +964,8 @@ void HandleRoot(void) WSContentSend_P(HTTP_SCRIPT_ROOT_PART2); WSContentSendStyle(); - WSContentSend_P("
"); - WSContentSend_P("
"); + WSContentSend_P(PSTR("
")); + WSContentSend_P(PSTR("
")); WSContentSend_P(PSTR("
")); @@ -1127,6 +975,8 @@ void HandleRoot(void) #endif // Not FIRMWARE_MINIMAL if (HTTP_ADMIN == Web.state) { + if (!Web.state_login) { WSContentSpaceButton(BUTTON_COGNITO_LOGIN); } + else { WSContentSpaceButton(BUTTON_COGNITO_LOGOUT); } WSContentSpaceButton(BUTTON_CONFIGURATION); WSContentButton(BUTTON_INFORMATION); WSContentButton(BUTTON_RESTART); @@ -1136,11 +986,6 @@ void HandleRoot(void) bool HandleRootStatusRefresh(void) { - if (!WebAuthenticate()) { - Webserver->requestAuthentication(); - return true; - } - if (!Webserver->hasArg("m")) { // Status refresh requested return false; } @@ -1154,7 +999,7 @@ bool HandleRootStatusRefresh(void) WSContentSend_P(PSTR("

")); WSContentSend_P(PSTR("\n\n")); // Prep for SSE if (!TasmotaGlobal.mqtt_connected) { - WSContentSend_P("
{loader}
"); + WSContentSend_P(PSTR("
{loader}
")); } WSContentEnd(); @@ -1183,8 +1028,6 @@ int32_t IsShutterWebButton(uint32_t idx) { void HandleConfiguration(void) { - if (!HttpCheckPriviledgedAccess()) { return; } - AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP D_CONFIGURATION)); WSContentStart_P(PSTR(D_CONFIGURATION)); @@ -1201,303 +1044,6 @@ void HandleConfiguration(void) /*-------------------------------------------------------------------------------------------*/ -void WSContentSendNiceLists(uint32_t option) { - char stemp[30]; // Template number and Sensor name - for (uint32_t i = 0; i < nitems(kGpioNiceList); i++) { // GPIO: }2'0'>None (0)}3}2'17'>Button1 (17)}3... - if (option && (1 == i)) { - WSContentSend_P(HTTP_MODULE_TEMPLATE_REPLACE_NO_INDEX, AGPIO(GPIO_USER), PSTR(D_SENSOR_USER)); // }2'255'>User}3 - } - uint32_t ridx = pgm_read_word(kGpioNiceList + i) & 0xFFE0; - uint32_t midx = BGPIO(ridx); - WSContentSend_P(HTTP_MODULE_TEMPLATE_REPLACE_NO_INDEX, ridx, GetTextIndexed(stemp, sizeof(stemp), midx, kSensorNames)); - } - WSContentSend_P(PSTR("\";")); - - WSContentSend_P(PSTR("hs=[")); - uint32_t midx; - bool first_done = false; - for (uint32_t i = 0; i < nitems(kGpioNiceList); i++) { // hs=[36,68,100,132,168,200,232,264,292,324,356,388,421,453]; - midx = pgm_read_word(kGpioNiceList + i); - if (midx & 0x001F) { - if (first_done) { WSContentSend_P(PSTR(",")); } - WSContentSend_P(PSTR("%d"), midx); - first_done = true; - } - } -#ifdef ESP8266 -#ifdef USE_ADC - for (uint32_t i = 0; i < nitems(kAdcNiceList); i++) { // hs=[36,68,100,132,168,200,232,264,292,324,356,388,421,453]; - midx = pgm_read_word(kAdcNiceList + i); - if (midx & 0x001F) { - if (first_done) { WSContentSend_P(PSTR(",")); } - WSContentSend_P(PSTR("%d"), midx); - first_done = true; - } - } -#endif // USE_ADC -#endif // ESP8266 - WSContentSend_P(PSTR("];")); -} - -#ifdef ESP8266 -#ifdef USE_ADC -void WSContentSendAdcNiceList(uint32_t option) { - char stemp[30]; // Template number and Sensor name - WSContentSend_P(PSTR("os=\"")); - for (uint32_t i = 0; i < nitems(kAdcNiceList); i++) { // GPIO: }2'0'>None}3}2'17'>Analog}3... - if (option && (1 == i)) { - WSContentSend_P(HTTP_MODULE_TEMPLATE_REPLACE_NO_INDEX, AGPIO(GPIO_USER), PSTR(D_SENSOR_USER)); // }2'15'>User}3 - } - uint32_t ridx = pgm_read_word(kAdcNiceList + i) & 0xFFE0; - uint32_t midx = BGPIO(ridx); - WSContentSend_P(HTTP_MODULE_TEMPLATE_REPLACE_NO_INDEX, ridx, GetTextIndexed(stemp, sizeof(stemp), midx, kSensorNames)); - } -} -#endif // USE_ADC -#endif // ESP8266 - -/*-------------------------------------------------------------------------------------------*/ - -void HandleTemplateConfiguration(void) { - if (!HttpCheckPriviledgedAccess()) { return; } - - if (Webserver->hasArg(F("save"))) { - TemplateSaveSettings(); - WebRestart(1); - return; - } - - char stemp[30]; // Template number and Sensor name - - WebGetArg(PSTR("t"), stemp, sizeof(stemp)); // 0 - 69 Template number - if (strlen(stemp)) { - uint32_t module = atoi(stemp); - uint32_t module_save = Settings->module; - Settings->module = module; - myio template_gp; - TemplateGpios(&template_gp); - gpio_flag flag = ModuleFlag(); - Settings->module = module_save; - - WSContentBegin(200, CT_PLAIN); - WSContentSend_P(PSTR("%s}1"), AnyModuleName(module).c_str()); // NAME: Generic - for (uint32_t i = 0; i < nitems(template_gp.io); i++) { // 17,148,29,149,7,255,255,255,138,255,139,255,255 -#if defined(ESP32) && CONFIG_IDF_TARGET_ESP32C3 - // ESP32C3 we always send all GPIOs, Flash are just hidden - WSContentSend_P(PSTR("%s%d"), (i>0)?",":"", template_gp.io[i]); -#else - if (!FlashPin(i)) { - WSContentSend_P(PSTR("%s%d"), (i>0)?",":"", template_gp.io[i]); - } -#endif - } - WSContentSend_P(PSTR("}1%d}1%d"), flag, Settings->user_template_base); // FLAG: 1 BASE: 17 - WSContentEnd(); - return; - } - - AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP D_CONFIGURE_TEMPLATE)); - - WSContentStart_P(PSTR(D_CONFIGURE_TEMPLATE)); - WSContentSend_P(HTTP_SCRIPT_MODULE_TEMPLATE); - - WSContentSend_P(HTTP_SCRIPT_TEMPLATE); - - WSContentSendNiceLists(1); - - WSContentSend_P(HTTP_SCRIPT_TEMPLATE2); - -#ifdef ESP8266 -#ifdef USE_ADC - WSContentSendAdcNiceList(1); - WSContentSend_P(HTTP_SCRIPT_TEMPLATE3); -#endif // USE_ADC -#endif // ESP8266 - - WSContentSend_P(HTTP_SCRIPT_TEMPLATE4); - for (uint32_t i = 0; i < sizeof(kModuleNiceList); i++) { // "}2'%d'>%s (%d)}3" - "}2'0'>Sonoff Basic (1)}3" - uint32_t midx = pgm_read_byte(kModuleNiceList + i); - WSContentSend_P(HTTP_MODULE_TEMPLATE_REPLACE_INDEX, midx, AnyModuleName(midx).c_str(), midx +1); - } - WSContentSend_P(HTTP_SCRIPT_TEMPLATE5); - - WSContentSendStyle(); - WSContentSend_P(HTTP_FORM_TEMPLATE); - WSContentSend_P(HTTP_TABLE100); - WSContentSend_P(PSTR("" D_TEMPLATE_NAME "" - "" D_BASE_TYPE "" - "" - "
")); - WSContentSend_P(HTTP_TABLE100); - for (uint32_t i = 0; i < MAX_GPIO_PIN; i++) { -#if defined(ESP32) && CONFIG_IDF_TARGET_ESP32C3 - // ESP32C3 all gpios are in the template, flash are hidden - bool hidden = FlashPin(i); - WSContentSend_P(PSTR("" D_GPIO "%d"), - hidden ? PSTR(" hidden") : "", - RedPin(i) ? WebColor(COL_TEXT_WARNING) : WebColor(COL_TEXT), i, (0==i) ? PSTR(" style='width:146px'") : "", i, i); - WSContentSend_P(PSTR(""), i); -#else - if (!FlashPin(i)) { - WSContentSend_P(PSTR("" D_GPIO "%d"), - RedPin(i) ? WebColor(COL_TEXT_WARNING) : WebColor(COL_TEXT), i, (0==i) ? PSTR(" style='width:146px'") : "", i, i); - WSContentSend_P(PSTR(""), i); - } -#endif - } - WSContentSend_P(PSTR("")); - - gpio_flag flag = ModuleFlag(); - if (flag.data) { - WSContentSend_P(HTTP_FORM_TEMPLATE_FLAG); - } - - WSContentSend_P(HTTP_FORM_END); - WSContentSpaceButton(BUTTON_CONFIGURATION); - WSContentStop(); -} - -uint16_t WebGetGpioArg(uint32_t i) { - char webindex[5]; // WebGetArg name - snprintf_P(webindex, sizeof(webindex), PSTR("g%d"), i); - char tmp[8]; // WebGetArg numbers only - WebGetArg(webindex, tmp, sizeof(tmp)); // GPIO - uint32_t gpio = (!strlen(tmp)) ? 0 : atoi(tmp); - char webindex2[5]; // WebGetArg name - snprintf_P(webindex2, sizeof(webindex2), PSTR("h%d"), i); - char tmp2[8]; // WebGetArg numbers only - WebGetArg(webindex2, tmp2, sizeof(tmp2)); - uint32_t value2 = (!strlen(tmp2)) ? 0 : atoi(tmp2) -1; - gpio += value2; - return gpio; -} - -void TemplateSaveSettings(void) { - char tmp[TOPSZ]; // WebGetArg NAME and GPIO/BASE/FLAG byte value - char command[300]; // Template command string - - WebGetArg(PSTR("s1"), tmp, sizeof(tmp)); // NAME - snprintf_P(command, sizeof(command), PSTR(D_CMND_TEMPLATE " {\"" D_JSON_NAME "\":\"%s\",\"" D_JSON_GPIO "\":["), tmp); - - uint32_t j = 0; - for (uint32_t i = 0; i < nitems(Settings->user_template.gp.io); i++) { -#if defined(ESP32) && CONFIG_IDF_TARGET_ESP32C3 - snprintf_P(command, sizeof(command), PSTR("%s%s%d"), command, (i>0)?",":"", WebGetGpioArg(i)); -#else - if (6 == i) { j = 9; } - if (8 == i) { j = 12; } - snprintf_P(command, sizeof(command), PSTR("%s%s%d"), command, (i>0)?",":"", WebGetGpioArg(j)); - j++; -#endif - } - - uint32_t flag = 0; - char webindex[5]; // WebGetArg name - for (uint32_t i = 0; i < GPIO_FLAG_USED; i++) { - snprintf_P(webindex, sizeof(webindex), PSTR("c%d"), i); - uint32_t state = Webserver->hasArg(webindex) << i; // FLAG - flag += state; - } - WebGetArg(PSTR("g99"), tmp, sizeof(tmp)); // BASE - uint32_t base = atoi(tmp) +1; - - snprintf_P(command, sizeof(command), PSTR("%s],\"" D_JSON_FLAG "\":%d,\"" D_JSON_BASE "\":%d}"), command, flag, base); - ExecuteWebCommand(command); -} - -/*-------------------------------------------------------------------------------------------*/ - -void HandleModuleConfiguration(void) { - if (!HttpCheckPriviledgedAccess()) { return; } - - if (Webserver->hasArg(F("save"))) { - ModuleSaveSettings(); - WebRestart(1); - return; - } - - AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP D_CONFIGURE_MODULE)); - - char stemp[30]; // Sensor name - uint32_t midx; - myio template_gp; - TemplateGpios(&template_gp); - - WSContentStart_P(PSTR(D_CONFIGURE_MODULE)); - WSContentSend_P(HTTP_SCRIPT_MODULE_TEMPLATE); - - WSContentSend_P(PSTR("function sl(){os=\"")); - uint32_t vidx = 0; - for (uint32_t i = 0; i <= sizeof(kModuleNiceList); i++) { // "}2'%d'>%s (%d)}3" - "}2'255'>UserTemplate (0)}3" - "}2'0'>Sonoff Basic (1)}3" - if (0 == i) { - midx = USER_MODULE; - vidx = 0; - } else { - midx = pgm_read_byte(kModuleNiceList + i -1); - vidx = midx +1; - } - WSContentSend_P(HTTP_MODULE_TEMPLATE_REPLACE_INDEX, midx, AnyModuleName(midx).c_str(), vidx); - } - WSContentSend_P(PSTR("\";sk(%d,99);os=\""), Settings->module); - - WSContentSendNiceLists(0); - - for (uint32_t i = 0; i < nitems(template_gp.io); i++) { - if (ValidGPIO(i, template_gp.io[i])) { - WSContentSend_P(PSTR("sk(%d,%d);"), TasmotaGlobal.my_module.io[i], i); // g0 - g17 - } - } - -#ifdef ESP8266 -#ifdef USE_ADC - WSContentSendAdcNiceList(0); - WSContentSend_P(PSTR("\";sk(%d," STR(ADC0_PIN) ");"), Settings->my_gp.io[(sizeof(myio) / 2) -1]); -#endif // USE_ADC -#endif // ESP8266 - - WSContentSend_P(PSTR("}wl(sl);")); - - WSContentSendStyle(); - WSContentSend_P(HTTP_FORM_MODULE, AnyModuleName(MODULE).c_str()); - for (uint32_t i = 0; i < nitems(template_gp.io); i++) { - if (ValidGPIO(i, template_gp.io[i])) { - snprintf_P(stemp, 3, PINS_WEMOS +i*2); - WSContentSend_P(PSTR("%s " D_GPIO "%d"), - (WEMOS==TasmotaGlobal.module_type)?stemp:"", i, i, i); - WSContentSend_P(PSTR(""), i); - } - } - WSContentSend_P(PSTR("")); - WSContentSend_P(HTTP_FORM_END); - WSContentSpaceButton(BUTTON_CONFIGURATION); - WSContentStop(); -} - -void ModuleSaveSettings(void) { - char tmp[8]; // WebGetArg numbers only - WebGetArg(PSTR("g99"), tmp, sizeof(tmp)); // Module - uint32_t new_module = (!strlen(tmp)) ? MODULE : atoi(tmp); - Settings->last_module = Settings->module; - Settings->module = new_module; - SetModuleType(); - myio template_gp; - TemplateGpios(&template_gp); - for (uint32_t i = 0; i < nitems(template_gp.io); i++) { - if (Settings->last_module != new_module) { - Settings->my_gp.io[i] = GPIO_NONE; - } else { - if (ValidGPIO(i, template_gp.io[i])) { - Settings->my_gp.io[i] = WebGetGpioArg(i); // Gpio - } - } - } - char command[32]; - snprintf_P(command, sizeof(command), PSTR(D_CMND_BACKLOG "0 " D_CMND_MODULE ";" D_CMND_GPIO)); - ExecuteWebCommand(command); -} - -/*-------------------------------------------------------------------------------------------*/ - const char kUnescapeCode[] = "&><\"\'\\"; const char kEscapeCode[] PROGMEM = "&|>|<|"|'|\"; @@ -1518,10 +1064,6 @@ String HtmlEscape(const String unescaped) { } void HandleWifiConfiguration(void) { - char tmp[TOPSZ]; // Max length is currently 150 - - if (!HttpCheckPriviledgedAccess(!WifiIsInManagerMode())) { return; } - AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP D_CONFIGURE_WIFI)); if (Webserver->hasArg(F("save")) && HTTP_MANAGER_RESET_ONLY != Web.state) { @@ -1543,18 +1085,14 @@ void HandleWifiConfiguration(void) { TasmotaGlobal.ota_state_flag = 0; // No OTA // TasmotaGlobal.blinks = 0; // Disable blinks initiated by WifiManager - WebGetArg(PSTR("s1"), tmp, sizeof(tmp)); // SSID1 - SettingsUpdateText(SET_STASSID1, tmp); - WebGetArg(PSTR("p1"), tmp, sizeof(tmp)); // PASSWORD1 - SettingsUpdateText(SET_STAPWD1, tmp); - WebGetArg(PSTR("d"), tmp, sizeof(tmp)); // DeviceName - SettingsUpdateText(SET_DEVICENAME, tmp); - SettingsUpdateText(SET_FRIENDLYNAME1, tmp); + WebGetArg(PSTR("s1"), ssid, sizeof(ssid)); // SSID1 + WebGetArg(PSTR("p1"), pwd, sizeof(pwd)); // PASSWORD1 + WebGetArg(PSTR("d"), deviceName, sizeof(deviceName)); // DeviceName AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_WIFI D_CONNECTING_TO_AP " %s " D_AS " %s ..."), - SettingsText(SET_STASSID1), TasmotaGlobal.hostname); + ssid, TasmotaGlobal.hostname); - WiFi.begin(SettingsText(SET_STASSID1), SettingsText(SET_STAPWD1)); + WiFi.begin(ssid, pwd); WebRestart(2); } else { @@ -1569,7 +1107,15 @@ void HandleWifiConfiguration(void) { if ( WIFI_TEST_FINISHED_SUCCESSFUL == Web.wifiTest ) { Web.wifiTest = WIFI_NOT_TESTING; #if (RESTART_AFTER_INITIAL_WIFI_CONFIG) - WebRestart(3); + if (TasmotaGlobal.cert_info_flag) { + SettingsUpdateText(SET_STASSID1, ssid); + SettingsUpdateText(SET_STAPWD1, pwd); + SettingsUpdateText(SET_DEVICENAME, deviceName); + SettingsUpdateText(SET_FRIENDLYNAME1, deviceName); + WebRestart(3); + } else { + Web.wifiTest = WIFI_TEST_FINISHED_BAD_NEED_CERT; + } #else HandleRoot(); #endif @@ -1738,9 +1284,11 @@ void HandleWifiConfiguration(void) { WSContentSend_P(PSTR("

")); if (WIFI_TESTING == Web.wifiTest) { - WSContentSend_P(PSTR(D_TRYING_TO_CONNECT "
%s

"), SettingsText(SET_STASSID1)); + WSContentSend_P(PSTR(D_TRYING_TO_CONNECT "
%s"), ssid); } else if (WIFI_TEST_FINISHED_BAD == Web.wifiTest) { - WSContentSend_P(PSTR(D_CONNECT_FAILED_TO " %s
" D_CHECK_CREDENTIALS ""), SettingsText(SET_STASSID1)); + WSContentSend_P(PSTR(D_CONNECT_FAILED_TO " %s
" D_CHECK_CREDENTIALS ""), ssid); + } else if (WIFI_TEST_FINISHED_BAD_NEED_CERT == Web.wifiTest) { + WSContentSend_P(PSTR(D_CONNECT_FAILED_TO " %s
" D_CHECK_CERTIFICATION ""), ssid); } WSContentSend_P(PSTR("

"), DEFAULT_SSID, DEFAULT_PASS); // More Options Button @@ -1770,156 +1318,8 @@ void WifiSaveSettings(void) { /*-------------------------------------------------------------------------------------------*/ -void HandleLoggingConfiguration(void) { - if (!HttpCheckPriviledgedAccess()) { return; } - - AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP D_CONFIGURE_LOGGING)); - - if (Webserver->hasArg("save")) { - LoggingSaveSettings(); - HandleConfiguration(); - return; - } - - WSContentStart_P(PSTR(D_CONFIGURE_LOGGING)); - WSContentSendStyle(); - WSContentSend_P(HTTP_FORM_LOG1); - char stemp1[45]; - char stemp2[32]; - uint8_t dlevel[4] = { LOG_LEVEL_INFO, LOG_LEVEL_INFO, LOG_LEVEL_NONE, LOG_LEVEL_NONE }; - for (uint32_t idx = 0; idx < 4; idx++) { - if ((2==idx) && !Settings->flag.mqtt_enabled) { continue; } // SetOption3 - Enable MQTT - uint32_t llevel = (0==idx)?Settings->seriallog_level:(1==idx)?Settings->weblog_level:(2==idx)?Settings->mqttlog_level:Settings->syslog_level; - WSContentSend_P(PSTR("

%s (%s)

")); - } - WSContentSend_P(HTTP_FORM_LOG2, SettingsText(SET_SYSLOG_HOST), Settings->syslog_port, Settings->tele_period); - WSContentSend_P(HTTP_FORM_END); - WSContentSpaceButton(BUTTON_CONFIGURATION); - WSContentStop(); -} - -void LoggingSaveSettings(void) { - String cmnd = F(D_CMND_BACKLOG "0 "); - cmnd += AddWebCommand(PSTR(D_CMND_SERIALLOG), PSTR("l0"), STR(SERIAL_LOG_LEVEL)); - cmnd += AddWebCommand(PSTR(D_CMND_WEBLOG), PSTR("l1"), STR(WEB_LOG_LEVEL)); - cmnd += AddWebCommand(PSTR(D_CMND_MQTTLOG), PSTR("l2"), STR(MQTT_LOG_LEVEL)); - cmnd += AddWebCommand(PSTR(D_CMND_SYSLOG), PSTR("l3"), STR(SYS_LOG_LEVEL)); - cmnd += AddWebCommand(PSTR(D_CMND_LOGHOST), PSTR("lh"), PSTR("1")); - cmnd += AddWebCommand(PSTR(D_CMND_LOGPORT), PSTR("lp"), PSTR("1")); - cmnd += AddWebCommand(PSTR(D_CMND_TELEPERIOD), PSTR("lt"), PSTR("1")); - ExecuteWebCommand((char*)cmnd.c_str()); -} - -/*-------------------------------------------------------------------------------------------*/ - -void HandleOtherConfiguration(void) { - if (!HttpCheckPriviledgedAccess()) { return; } - - AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP D_CONFIGURE_OTHER)); - - if (Webserver->hasArg(F("save"))) { - OtherSaveSettings(); - WebRestart(1); - return; - } - - WSContentStart_P(PSTR(D_CONFIGURE_OTHER)); - WSContentSendStyle(); - - TemplateJson(); -#ifdef MQTT_DATA_STRING - WSContentSend_P(HTTP_FORM_OTHER, TasmotaGlobal.mqtt_data.c_str(), (USER_MODULE == Settings->module) ? PSTR(" checked disabled") : "", -#else - WSContentSend_P(HTTP_FORM_OTHER, TasmotaGlobal.mqtt_data, (USER_MODULE == Settings->module) ? PSTR(" checked disabled") : "", -#endif - (Settings->flag.mqtt_enabled) ? PSTR(" checked") : "", // SetOption3 - Enable MQTT - SettingsText(SET_FRIENDLYNAME1), SettingsText(SET_DEVICENAME)); - - char stemp[32]; - uint32_t maxfn = (TasmotaGlobal.devices_present > MAX_FRIENDLYNAMES) ? MAX_FRIENDLYNAMES : (!TasmotaGlobal.devices_present) ? 1 : TasmotaGlobal.devices_present; -#ifdef USE_SONOFF_IFAN - if (IsModuleIfan()) { maxfn = 1; } -#endif // USE_SONOFF_IFAN - for (uint32_t i = 0; i < maxfn; i++) { - snprintf_P(stemp, sizeof(stemp), PSTR("%d"), i +1); - WSContentSend_P(PSTR("" D_FRIENDLY_NAME " %d (" FRIENDLY_NAME "%s)

"), - i +1, - (i) ? stemp : "", - i, - (i) ? stemp : "", - SettingsText(SET_FRIENDLYNAME1 + i)); - } - -#ifdef USE_EMULATION -#if defined(USE_EMULATION_WEMO) || defined(USE_EMULATION_HUE) - WSContentSend_P(PSTR("

 " D_EMULATION " 

")); // Keep close to Friendlynames so do not use
- for (uint32_t i = 0; i < EMUL_MAX; i++) { -#ifndef USE_EMULATION_WEMO - if (i == EMUL_WEMO) { i++; } -#endif -#ifndef USE_EMULATION_HUE - if (i == EMUL_HUE) { i++; } -#endif - if (i < EMUL_MAX) { - WSContentSend_P(PSTR("%s %s
"), // Different id only used for labels - i, i, - (i == Settings->flag2.emulation) ? PSTR(" checked") : "", - GetTextIndexed(stemp, sizeof(stemp), i, kEmulationOptions), - (i == EMUL_NONE) ? "" : (i == EMUL_WEMO) ? PSTR(D_SINGLE_DEVICE) : PSTR(D_MULTI_DEVICE)); - } - } - WSContentSend_P(PSTR("

")); -#endif // USE_EMULATION_WEMO || USE_EMULATION_HUE -#endif // USE_EMULATION - - WSContentSend_P(HTTP_FORM_END); - WSContentSpaceButton(BUTTON_CONFIGURATION); - WSContentStop(); -} - -void OtherSaveSettings(void) { - String cmnd = F(D_CMND_BACKLOG "0 "); - cmnd += AddWebCommand(PSTR(D_CMND_WEBPASSWORD "2"), PSTR("wp"), PSTR("\"")); - cmnd += F(";" D_CMND_SO "3 "); - cmnd += Webserver->hasArg(F("b1")); - cmnd += AddWebCommand(PSTR(D_CMND_DEVICENAME), PSTR("dn"), PSTR("\"")); - char webindex[5]; - char cmnd2[24]; // ";Module 0;Template " - for (uint32_t i = 0; i < MAX_FRIENDLYNAMES; i++) { - snprintf_P(webindex, sizeof(webindex), PSTR("a%d"), i); - snprintf_P(cmnd2, sizeof(cmnd2), PSTR(D_CMND_FN "%d"), i +1); - cmnd += AddWebCommand(cmnd2, webindex, PSTR("\"")); - } - -#ifdef USE_EMULATION -#if defined(USE_EMULATION_WEMO) || defined(USE_EMULATION_HUE) - cmnd += AddWebCommand(PSTR(D_CMND_EMULATION), PSTR("b2"), PSTR("0")); -#endif // USE_EMULATION_WEMO || USE_EMULATION_HUE -#endif // USE_EMULATION - - String tmpl = Webserver->arg(F("t1")); // {"NAME":"12345678901234","GPIO":[255,255,255,255,255,255,255,255,255,255,255,255,255],"FLAG":255,"BASE":255,"CMND":"SO123 1;SO99 0"} - if (tmpl.length() && (tmpl.length() < MQTT_MAX_PACKET_SIZE)) { - snprintf_P(cmnd2, sizeof(cmnd2), PSTR(";%s" D_CMND_TEMPLATE " "), (Webserver->hasArg(F("t2"))) ? PSTR(D_CMND_MODULE " 0;") : ""); - cmnd += cmnd2 + tmpl; - } - ExecuteWebCommand((char*)cmnd.c_str()); -} - -/*-------------------------------------------------------------------------------------------*/ - void HandleBackupConfiguration(void) { - if (!HttpCheckPriviledgedAccess()) { return; } - AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP D_BACKUP_CONFIGURATION)); uint32_t config_len = SettingsConfigBackup(); @@ -1942,8 +1342,6 @@ void HandleBackupConfiguration(void) void HandleResetConfiguration(void) { - if (!HttpCheckPriviledgedAccess(!WifiIsInManagerMode())) { return; } - AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP D_RESET_CONFIGURATION)); WSContentStart_P(PSTR(D_RESET_CONFIGURATION), !WifiIsInManagerMode()); @@ -1960,13 +1358,11 @@ void HandleResetConfiguration(void) void HandleFactoryResetConfiguration(void) { - if (!HttpCheckPriviledgedAccess(!WifiIsInManagerMode())) { return; } - AddLog(LOG_LEVEL_DEBUG, PSTR("공장 초기화 중...")); WSContentStart_P(PSTR("공장 초기화"), !WifiIsInManagerMode()); WSContentSendStyle(); - WSContentSend_P(PSTR("
" D_CONFIGURATION_RESET "
")); + WSContentSend_P(PSTR("
공장 초기화
")); WSContentSend_P(HTTP_MSG_RSTRT); WSContentSpaceButton(BUTTON_MAIN); WSContentStop(); @@ -1978,8 +1374,6 @@ void HandleFactoryResetConfiguration(void) void HandleRestoreConfiguration(void) { - if (!HttpCheckPriviledgedAccess()) { return; } - AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP D_RESTORE_CONFIGURATION)); WSContentStart_P(PSTR(D_RESTORE_CONFIGURATION)); @@ -2000,8 +1394,6 @@ void HandleRestoreConfiguration(void) void HandleInformation(void) { - if (!HttpCheckPriviledgedAccess()) { return; } - float freemem = ((float)ESP_getFreeHeap()) / 1024; AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP D_INFORMATION)); @@ -2135,8 +1527,8 @@ void HandleInformation(void) WSContentSend_PD(PSTR("}1" D_FREE_MEMORY "}2%1_f kB"), &freemem); #endif // ESP32 WSContentSend_P(PSTR("")); - WSContentSend_P("\";s=o.replace(/}1/g,\"\").replace(/}2/g,\"\");eb('hide').innerHTML=s;}wl(hide);"); - WSContentSend_P("
"); + WSContentSend_P(PSTR("\";s=o.replace(/}1/g,\"\").replace(/}2/g,\"\");eb('hide').innerHTML=s;}wl(hide);")); + WSContentSend_P(PSTR("
")); WSContentSend_P(PSTR("")); WSContentSpaceButton(BUTTON_MAIN); @@ -2193,8 +1585,6 @@ uint32_t BUploadWriteBuffer(uint8_t *buf, size_t size) { #endif // USE_WEB_FW_UPGRADE void HandleUpgradeFirmware(void) { - if (!HttpCheckPriviledgedAccess()) { return; } - AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP D_FIRMWARE_UPGRADE)); WSContentStart_P(PSTR(D_FIRMWARE_UPGRADE)); @@ -2208,8 +1598,6 @@ void HandleUpgradeFirmware(void) { } void HandleUpgradeFirmwareStart(void) { - if (!HttpCheckPriviledgedAccess()) { return; } - char command[TOPSZ + 10]; // OtaUrl AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP D_UPGRADE_STARTED)); @@ -2235,8 +1623,6 @@ void HandleUpgradeFirmwareStart(void) { } void HandleUploadDone(void) { - if (!HttpCheckPriviledgedAccess()) { return; } - #if defined(USE_ZIGBEE_EZSP) if ((UPL_EFR32 == Web.upload_file_type) && !Web.upload_error && BUpload.ready) { BUpload.ready = false; // Make sure not to follow thru again @@ -2575,25 +1961,8 @@ void HandlePreflightRequest(void) void HandleHttpCommand(void) { - if (!HttpCheckPriviledgedAccess(false)) { return; } - AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP D_COMMAND)); - if (!WebAuthenticate()) { - // Prefer authorization via HTTP header (Basic auth), if it fails, use legacy method via GET parameters - char tmp1[33]; - WebGetArg(PSTR("user"), tmp1, sizeof(tmp1)); - char tmp2[strlen(SettingsText(SET_WEBPWD)) + 2]; // Need space for an entered password longer than set password - WebGetArg(PSTR("password"), tmp2, sizeof(tmp2)); - - if (!(!strcmp(tmp1, WEB_USERNAME) && !strcmp(tmp2, SettingsText(SET_WEBPWD)))) { - WSContentBegin(401, CT_APP_JSON); - WSContentSend_P(PSTR("{\"" D_RSLT_WARNING "\":\"" D_NEED_USER_AND_PASSWORD "\"}")); - WSContentEnd(); - return; - } - } - WSContentBegin(200, CT_APP_JSON); String svalue = Webserver->arg(F("cmnd")); if (svalue.length() && (svalue.length() < MQTT_MAX_PACKET_SIZE)) { @@ -2623,80 +1992,6 @@ void HandleHttpCommand(void) WSContentEnd(); } -/*-------------------------------------------------------------------------------------------*/ - -void HandleManagement(void) -{ - if (!HttpCheckPriviledgedAccess()) { return; } - - AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP D_MANAGEMENT)); - - WSContentStart_P(PSTR(D_MANAGEMENT)); - WSContentSendStyle(); - - WSContentButton(BUTTON_CONSOLE); - - XdrvMailbox.index = 0; - XdrvCall(FUNC_WEB_ADD_CONSOLE_BUTTON); - XsnsCall(FUNC_WEB_ADD_CONSOLE_BUTTON); - - WSContentSend_P(PSTR("
")); // 5px padding - XdrvCall(FUNC_WEB_ADD_MANAGEMENT_BUTTON); - - WSContentSpaceButton(BUTTON_MAIN); - WSContentStop(); -} - -void HandleConsole(void) -{ - if (!HttpCheckPriviledgedAccess()) { return; } - - if (Webserver->hasArg(F("c2"))) { // Console refresh requested - HandleConsoleRefresh(); - return; - } - - AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP D_CONSOLE)); - - WSContentStart_P(PSTR(D_CONSOLE)); - WSContentSend_P(HTTP_SCRIPT_CONSOL, Settings->web_refresh); - WSContentSendStyle(); - WSContentSend_P(HTTP_FORM_CMND); - WSContentSpaceButton((WebUseManagementSubmenu()) ? BUTTON_MANAGEMENT : BUTTON_MAIN); - WSContentStop(); -} - -void HandleConsoleRefresh(void) -{ - String svalue = Webserver->arg(F("c1")); - if (svalue.length() && (svalue.length() < MQTT_MAX_PACKET_SIZE)) { - AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_COMMAND "%s"), svalue.c_str()); - ExecuteWebCommand((char*)svalue.c_str(), SRC_WEBCONSOLE); - } - - char stmp[8]; - WebGetArg(PSTR("c2"), stmp, sizeof(stmp)); - uint32_t index = 0; // Initial start, dump all - if (strlen(stmp)) { index = atoi(stmp); } - - WSContentBegin(200, CT_PLAIN); - WSContentSend_P(PSTR("%d}1%d}1"), TasmotaGlobal.log_buffer_pointer, Web.reset_web_log_flag); - if (!Web.reset_web_log_flag) { - index = 0; - Web.reset_web_log_flag = true; - } - bool cflg = (index); - char* line; - size_t len; - while (GetLog(Settings->weblog_level, &index, &line, &len)) { - if (cflg) { WSContentSend_P(PSTR("\n")); } - WSContentSend(line, len -1); - cflg = true; - } - WSContentSend_P(PSTR("}1")); - WSContentEnd(); -} - /********************************************************************************************/ void HandleNotFound(void) @@ -2743,59 +2038,6 @@ bool CaptivePortal(void) /*********************************************************************************************/ -void HandleDeviceInfo(void) { - WSContentBegin(200, CT_APP_JSON); - WSContentSend_P(PSTR("{\"message\":\"Success\", \"data\":{\"nickname\":\"%s\", \"mac\":\"%s\", \"type\":\"%s\"}}"), SettingsText(SET_FRIENDLYNAME1), WiFi.macAddress().c_str(), DEVICE_TYPE); - WSContentEnd(); -} - -void HandleCertsInfo(void) { - if ((strlen(AmazonClientCert) == 0) || strlen(AmazonPrivateKey) == 0) { - WSContentBegin(500, CT_APP_JSON); - WSContentSend_P(PSTR("{\"message\":\"Fail\"}")); - WSContentEnd(); - return; - } - - WSContentBegin(200, CT_APP_JSON); - WSContentSend_P(PSTR("{\"message\":\"Success\", \"data\":{\"cert\":\"%s\", \"key\":\"%s\"}}"), AmazonClientCert, AmazonPrivateKey); - WSContentEnd(); -} - -void HandleCertsConfiguration(void) { - if(!Webserver->hasArg(F("plain"))) { - WSContentBegin(500, CT_APP_JSON); - WSContentSend_P(PSTR("{\"message\":\"Fail\"}")); - WSContentEnd(); - return; - } - - JsonParser parser((char*) Webserver->arg("plain").c_str()); - JsonParserObject stateObject = parser.getRootObject(); - String cert = stateObject["cert"].getStr(); - String key = stateObject["key"].getStr(); - char* certCharType = (char*)cert.c_str(); - char* keyCharType = (char*)key.c_str(); - -/* TODO: 인증서 사이즈 체크 예외코드 작성 - if(cert.length() != 256 || key.length() < 10) { - WSContentBegin(500, CT_APP_JSON); - WSContentSend_P(PSTR("{\"message\":\"Fail\"}")); - WSContentEnd(); - return; - } -*/ - memcpy(AmazonClientCert, certCharType, strlen(certCharType)); - memcpy(AmazonPrivateKey, keyCharType, strlen(keyCharType)); - MqttDisconnect(); - ConvertTlsFile(0); - ConvertTlsFile(1); - - WSContentBegin(200, CT_APP_JSON); - WSContentSend_P(PSTR("{\"message\":\"Success\"}")); - WSContentEnd(); -} - int WebSend(char *buffer) { // [tasmota] POWER1 ON --> Sends http://tasmota/cm?cmnd=POWER1 ON @@ -2906,7 +2148,7 @@ const char kWebCommands[] PROGMEM = "|" // No prefix #if defined(USE_SENDMAIL) || defined(USE_ESP32MAIL) D_CMND_SENDMAIL "|" #endif - D_CMND_WEBSERVER "|" D_CMND_WEBPASSWORD "|" D_CMND_WEBLOG "|" D_CMND_WEBREFRESH "|" D_CMND_WEBSEND "|" D_CMND_WEBCOLOR "|" + D_CMND_WEBSERVER "|" D_CMND_WEBREFRESH "|" D_CMND_WEBSEND "|" D_CMND_WEBSENSOR "|" D_CMND_WEBBUTTON "|" D_CMND_CORS; void (* const WebCommand[])(void) PROGMEM = { @@ -2916,7 +2158,7 @@ void (* const WebCommand[])(void) PROGMEM = { #if defined(USE_SENDMAIL) || defined(USE_ESP32MAIL) &CmndSendmail, #endif - &CmndWebServer, &CmndWebPassword, &CmndWeblog, &CmndWebRefresh, &CmndWebSend, &CmndWebColor, + &CmndWebServer, &CmndWebRefresh, &CmndWebSend, &CmndWebSensor, &CmndWebButton, &CmndCors }; /*********************************************************************************************\ @@ -2970,30 +2212,6 @@ void CmndWebServer(void) } } -void CmndWebPassword(void) -{ - bool show_asterisk = (2 == XdrvMailbox.index); - if (XdrvMailbox.data_len > 0) { - SettingsUpdateText(SET_WEBPWD, (SC_CLEAR == Shortcut()) ? "" : (SC_DEFAULT == Shortcut()) ? WEB_PASSWORD : XdrvMailbox.data); - if (!show_asterisk) { - ResponseCmndChar(SettingsText(SET_WEBPWD)); - } - } else { - show_asterisk = true; - } - if (show_asterisk) { - Response_P(S_JSON_COMMAND_ASTERISK, XdrvMailbox.command); - } -} - -void CmndWeblog(void) -{ - if ((XdrvMailbox.payload >= LOG_LEVEL_NONE) && (XdrvMailbox.payload <= LOG_LEVEL_DEBUG_MORE)) { - Settings->weblog_level = XdrvMailbox.payload; - } - ResponseCmndNumber(Settings->weblog_level); -} - void CmndWebRefresh(void) { if ((XdrvMailbox.payload > 999) && (XdrvMailbox.payload <= 65000)) { @@ -3011,31 +2229,6 @@ void CmndWebSend(void) } } -void CmndWebColor(void) -{ - if (XdrvMailbox.data_len > 0) { - if (strchr(XdrvMailbox.data, '{') == nullptr) { // If no JSON it must be parameter - if ((XdrvMailbox.data_len > 3) && (XdrvMailbox.index > 0) && (XdrvMailbox.index <= COL_LAST)) { - WebHexCode(XdrvMailbox.index -1, XdrvMailbox.data); - } - else if (0 == XdrvMailbox.payload) { - SettingsDefaultWebColor(); - } - } - else { -#ifndef FIRMWARE_MINIMAL // if tasmota-minimal, read only and don't parse JSON - JsonWebColor(XdrvMailbox.data); -#endif // FIRMWARE_MINIMAL - } - } - Response_P(PSTR("{\"" D_CMND_WEBCOLOR "\":[")); - for (uint32_t i = 0; i < COL_LAST; i++) { - if (i) { ResponseAppend_P(PSTR(",")); } - ResponseAppend_P(PSTR("\"#%06x\""), WebColor(i)); - } - ResponseAppend_P(PSTR("]}")); -} - void CmndWebSensor(void) { if (XdrvMailbox.index < MAX_XSNS_DRIVERS) { diff --git a/tasmota/xdrv_01_webserver_secure.ino b/tasmota/xdrv_01_webserver_secure.ino new file mode 100644 index 000000000000..5e8795fa0709 --- /dev/null +++ b/tasmota/xdrv_01_webserver_secure.ino @@ -0,0 +1,333 @@ +#include "FS.h" + +struct WEBSECURE { + bool state_HTTPS = false; + bool state_login = false; +} WebSecure; + +void StartWebserverSecure(void) +{ + if (!WebSecure.state_HTTPS) { + if (!WebserverSecure) { + WebserverSecure = new ESP8266WebServerSecure(443); + WebserverSecure->getServer().setRSACert(new BearSSL::X509List(serverCert), new BearSSL::PrivateKey(serverKey)); + // WebserverSecure->getServer().setBufferSizes(1024, 1024); + WebserverSecure->getServer().setBufferSizes(2048, 1024); + WebserverSecure->on(F("/config"), HTTP_POST, HandleConfigurationWithApp); + } + + WebserverSecure->begin(); // Web server start + } + if (!WebSecure.state_HTTPS) { + AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_HTTP "HTTPS" D_WEBSERVER_ACTIVE_ON " %s%s " D_WITH_IP_ADDRESS " %_I"), + NetworkHostname(), (Mdns.begun) ? PSTR(".local") : "", (uint32_t)WiFi.localIP()); + WebSecure.state_HTTPS = true; + } +} + +// TODO: 메모리 회수 코드 추가 +void StopWebserverSecure(void) +{ + if (WebSecure.state_HTTPS) { + WebserverSecure->close(); + WebSecure.state_HTTPS = false; + AddLog(LOG_LEVEL_INFO, PSTR("HTTPS 웹서버 종료")); + } +} + +/*********************************************************************************************/ + +void HttpHeaderCorsSecure(void) +{ + if (strlen(SettingsText(SET_CORS))) { + WebserverSecure->sendHeader(F("Access-Control-Allow-Origin"), SettingsText(SET_CORS)); + } +} + +void WSHeaderSendSecure(void) +{ + char server[32]; + // TODO: ZIoT 버전 변경 + snprintf_P(server, sizeof(server), PSTR("Tasmota/%s (%s)"), TasmotaGlobal.version, GetDeviceHardware().c_str()); + WebserverSecure->sendHeader(F("Server"), server); + WebserverSecure->sendHeader(F("Cache-Control"), F("no-cache, no-store, must-revalidate")); + WebserverSecure->sendHeader(F("Pragma"), F("no-cache")); + WebserverSecure->sendHeader(F("Expires"), F("-1")); + HttpHeaderCorsSecure(); +} + +/********************************************************************************************** +* HTTP Content Page handler +**********************************************************************************************/ + +void WSSendSecure(int code, int ctype, const String& content) +{ + char ct[25]; // strlen("application/octet-stream") +1 = Longest Content type string + WebserverSecure->send(code, GetTextIndexed(ct, sizeof(ct), ctype, kContentTypes), content); +} + +/********************************************************************************************** +* HTTP Content Chunk handler +**********************************************************************************************/ + +void WSContentBeginSecure(int code, int ctype) { + WebserverSecure->client().flush(); + WSHeaderSendSecure(); + WebserverSecure->setContentLength(CONTENT_LENGTH_UNKNOWN); + WSSendSecure(code, ctype, ""); // Signal start of chunked content + Web.chunk_buffer = ""; +} + +void _WSContentSendSecure(const char* content, size_t size) { // Lowest level sendContent for all core versions + WebserverSecure->sendContent(content, size); + +#ifdef USE_DEBUG_DRIVER + ShowFreeMem(PSTR("WSContentSend")); +#endif + DEBUG_CORE_LOG(PSTR("WEB: Chunk size %d"), size); +} + +void _WSContentSendSecure(const String& content) { // Low level sendContent for all core versions + _WSContentSendSecure(content.c_str(), content.length()); +} + +void WSContentFlushSecure(void) { + if (Web.chunk_buffer.length() > 0) { + _WSContentSendSecure(Web.chunk_buffer); // Flush chunk buffer + Web.chunk_buffer = ""; + } +} + +void WSContentSendSecure(const char* content, size_t size) { + WSContentFlushSecure(); + _WSContentSendSecure(content, size); +} + +void _WSContentSendBufferSecure(bool decimal, const char * formatP, va_list arg) { + char* content = ext_vsnprintf_malloc_P(formatP, arg); + if (content == nullptr) { return; } // Avoid crash + + int len = strlen(content); + if (0 == len) { return; } // No content + + if (decimal && (D_DECIMAL_SEPARATOR[0] != '.')) { + for (uint32_t i = 0; i < len; i++) { + if ('.' == content[i]) { + content[i] = D_DECIMAL_SEPARATOR[0]; + } + } + } + + if (len < CHUNKED_BUFFER_SIZE) { // Append chunk buffer with small content + Web.chunk_buffer += content; + len = Web.chunk_buffer.length(); + } + + if (len >= CHUNKED_BUFFER_SIZE) { // Either content or chunk buffer is oversize + WSContentFlushSecure(); // Send chunk buffer before possible content oversize + } + if (strlen(content) >= CHUNKED_BUFFER_SIZE) { // Content is oversize + _WSContentSendSecure(content); // Send content + } + + free(content); +} + +void WSContentSend_PSecure(const char* formatP, ...) { // Content send snprintf_P char data + // This uses char strings. Be aware of sending %% if % is needed + va_list arg; + va_start(arg, formatP); + _WSContentSendBufferSecure(false, formatP, arg); + va_end(arg); +} + +void WSContentSend_PDSecure(const char* formatP, ...) { // Content send snprintf_P char data checked for decimal separator + // This uses char strings. Be aware of sending %% if % is needed + va_list arg; + va_start(arg, formatP); + _WSContentSendBufferSecure(true, formatP, arg); + va_end(arg); +} + +void WSContentStart_PSecure(const char* title, bool auth) +{ + WSContentBeginSecure(200, CT_HTML); + + if (title != nullptr) { + WSContentSend_PSecure(HTTP_HEADER1, PSTR(D_HTML_LANGUAGE), SettingsText(SET_DEVICENAME), title); + } +} + +void WSContentStart_PSecure(const char* title) +{ + WSContentStart_PSecure(title, true); +} + +void WSContentSendStyle_PSecure(const char* formatP, ...) +{ + if ( WifiIsInManagerMode() && (!Web.initial_config) ) { + if (WifiConfigCounter()) { + WSContentSend_PSecure(HTTP_SCRIPT_COUNTER); + } + } + //WSContentSend_P(HTTP_SCRIPT_LOADER); + WSContentSend_PSecure(HTTP_HEAD_LAST_SCRIPT); + + WSContentSend_PSecure(HTTP_HEAD_STYLE1, WebColor(COL_FORM), WebColor(COL_INPUT), WebColor(COL_INPUT_TEXT), WebColor(COL_INPUT), + WebColor(COL_INPUT_TEXT), PSTR(""), PSTR(""), WebColor(COL_BACKGROUND)); + WSContentSend_PSecure(HTTP_HEAD_STYLE2, WebColor(COL_BUTTON), WebColor(COL_BUTTON_TEXT), WebColor(COL_BUTTON_HOVER), + WebColor(COL_BUTTON_RESET), WebColor(COL_BUTTON_RESET_HOVER), WebColor(COL_BUTTON_SAVE), WebColor(COL_BUTTON_SAVE_HOVER), + WebColor(COL_BUTTON)); +#ifdef USE_ZIGBEE + WSContentSend_PSecure(HTTP_HEAD_STYLE_ZIGBEE); +#endif // USE_ZIGBEE + if (formatP != nullptr) { + // This uses char strings. Be aware of sending %% if % is needed + va_list arg; + va_start(arg, formatP); + _WSContentSendBufferSecure(false, formatP, arg); + va_end(arg); + } + WSContentSend_PSecure(HTTP_HEAD_STYLE_LOADER); + WSContentSend_PSecure(HTTP_HEAD_STYLE3, WebColor(COL_TEXT), +#ifdef FIRMWARE_MINIMAL + WebColor(COL_TEXT_WARNING), +#endif + WebColor(COL_TITLE), + "", SettingsText(SET_DEVICENAME)); + + // SetOption53 - Show hostname and IP address in GUI main menu +#if (RESTART_AFTER_INITIAL_WIFI_CONFIG) + if (Settings->flag3.gui_hostname_ip) { +#else + if ( Settings->flag3.gui_hostname_ip || ( (WiFi.getMode() == WIFI_AP_STA) && (!Web.initial_config) ) ) { +#endif + bool lip = (static_cast(WiFi.localIP()) != 0); + bool sip = (static_cast(WiFi.softAPIP()) != 0); + WSContentSend_PSecure(PSTR("

%s%s (%s%s%s)

"), // tasmota.local (192.168.2.12, 192.168.4.1) + NetworkHostname(), + (Mdns.begun) ? PSTR(".local") : "", + (lip) ? WiFi.localIP().toString().c_str() : "", + (lip && sip) ? ", " : "", + (sip) ? WiFi.softAPIP().toString().c_str() : ""); + } + WSContentSend_PSecure(PSTR("")); +} + +void WSContentSendStyleSecure(void) +{ + WSContentSendStyle_PSecure(nullptr); +} + +void WSContentTextCenterStartSecure(uint32_t color) { + WSContentSend_PSecure(PSTR("
"), color); +} + +void WSContentButtonSecure(uint32_t title_index, bool show=true) +{ + char action[4]; + char title[100]; // Large to accomodate UTF-16 as used by Russian + + WSContentSend_PSecure(PSTR("

"), + GetTextIndexed(confirm, sizeof(confirm), title_index, kButtonConfirm), + (!title_index) ? PSTR("rst") : PSTR("non"), + GetTextIndexed(title, sizeof(title), title_index, kButtonTitle)); + } else { + WSContentSend_PSecure(PSTR(">

"), + GetTextIndexed(title, sizeof(title), title_index, kButtonTitle)); + } +} + +void WSContentSpaceButtonSecure(uint32_t title_index, bool show=true) +{ + WSContentSend_PSecure(PSTR("
"),title_index, show ? "block":"none"); // 5px padding + WSContentButtonSecure(title_index, show); +} + +void WSContentSend_TempSecure(const char *types, float f_temperature) { + WSContentSend_PDSecure(HTTP_SNS_F_TEMP, types, Settings->flag2.temperature_resolution, &f_temperature, TempUnit()); +} + +void WSContentSend_VoltageSecure(const char *types, float f_voltage) { + WSContentSend_PDSecure(HTTP_SNS_F_VOLTAGE, types, Settings->flag2.voltage_resolution, &f_voltage); +} + +void WSContentSend_CurrentMASecure(const char *types, float f_current) { + WSContentSend_PDSecure(HTTP_SNS_F_CURRENT_MA, types, Settings->flag2.current_resolution, &f_current); +} + +void WSContentSend_THDSecure(const char *types, float f_temperature, float f_humidity) +{ + WSContentSend_TempSecure(types, f_temperature); + + char parameter[FLOATSZ]; + dtostrfd(f_humidity, Settings->flag2.humidity_resolution, parameter); + WSContentSend_PDSecure(HTTP_SNS_HUM, types, parameter); + dtostrfd(CalcTempHumToDew(f_temperature, f_humidity), Settings->flag2.temperature_resolution, parameter); + WSContentSend_PDSecure(HTTP_SNS_DEW, types, parameter, TempUnit()); +} + +void WSContentEndSecure(void) +{ + WSContentSendSecure("", 0); // Signal end of chunked content + WebserverSecure->client().stop(); +} + +void WSContentStopSecure(void) +{ + if ( WifiIsInManagerMode() && (!Web.initial_config) ) { + if (WifiConfigCounter()) { + WSContentSend_PSecure(HTTP_COUNTER); + } + } + // TODO: ZIoT 버전 변경 + WSContentSend_PSecure(HTTP_END, WiFi.macAddress().c_str(), TasmotaGlobal.version); + WSContentEndSecure(); +} + +/*********************************************************************************************/ + +void HandleConfigurationWithApp(void) { + bool save_result = false; + if(!WebserverSecure->hasArg(F("plain"))) { + WSContentBeginSecure(500, CT_APP_JSON); + WSContentSend_PSecure(PSTR("{\"message\":\"Failed\" \"resason\":\"1\" \"data\":\"Server received empty request message\"}")); + WSContentEndSecure(); + return; + } + + JsonParser parser((char*) WebserverSecure->arg("plain").c_str()); + JsonParserObject stateObject = parser.getRootObject(); + + String idToken = stateObject["idToken"].getStr(); + String ssid = stateObject["ssid1"].getStr(); + String pwd = stateObject["pwd1"].getStr(); + + if (idToken.length()) { + char* temp = (char*)idToken.c_str(); + save_result = TfsSaveFile("/idToken.txt", (uint8_t*)temp, 1024); + } + + if (!save_result || !ssid.length() || !pwd.length()) { + WSContentBeginSecure(400, CT_APP_JSON); + WSContentSend_PSecure(PSTR("{\"message\":\"Failed\" \"resason\":\"2\" \"data\":\"Check token, ssid, and pwd\"}")); + WSContentEndSecure(); + return; + } else { + SettingsUpdateText(SET_ID_TOKEN, "TRUE"); + SettingsUpdateText(SET_STASSID1, (char*)ssid.c_str()); + SettingsUpdateText(SET_STAPWD1, (char*)pwd.c_str()); + } + + WSContentBeginSecure(200, CT_APP_JSON); + WSContentSend_PSecure(PSTR("{\"message\":\"Success\"}")); + WSContentEndSecure(); + + TasmotaGlobal.restart_flag = 2; +} \ No newline at end of file diff --git a/tasmota/xdrv_02_9_mqtt.ino b/tasmota/xdrv_02_9_mqtt.ino index 70f830f7c6b4..9eaf144b88a7 100644 --- a/tasmota/xdrv_02_9_mqtt.ino +++ b/tasmota/xdrv_02_9_mqtt.ino @@ -208,7 +208,6 @@ void MqttInit(void) { if (host.indexOf(F(".iot.")) && host.endsWith(F(".amazonaws.com"))) { // look for ".iot." and ".amazonaws.com" in the domain name Settings->flag4.mqtt_no_retain = true; } - if (Mqtt.mqtt_tls) { if (!tlsClient) { #ifdef ESP32 @@ -224,6 +223,9 @@ void MqttInit(void) { tlsClient->setClientECCert(AWS_IoT_Client_Certificate, AWS_IoT_Private_Key, 0xFFFF /* all usages, don't care */, 0); + TasmotaGlobal.cert_info_flag = 1; + } else { + TasmotaGlobal.cert_info_flag = 0; } #endif @@ -1592,13 +1594,16 @@ void loadTlsDir(void) { const char ALLOCATE_ERROR[] PROGMEM = "TLSKey " D_JSON_ERROR ": cannot allocate buffer."; -void ConvertTlsFile(uint8_t cert) { +bool ConvertTlsFile(uint8_t cert) { tls_dir_t *tls_dir_write; + int freeheap = ESP.getFreeHeap(); + printf("free heap size: %d\n", freeheap); uint8_t *spi_buffer = (uint8_t*) malloc(tls_spi_len); + printf("spi_buffer\n"); if (!spi_buffer) { AddLog(LOG_LEVEL_ERROR, ALLOCATE_ERROR); - return; + return false; } if (tls_spi_start != nullptr) { // safeguard for ESP32 memcpy_P(spi_buffer, tls_spi_start, tls_spi_len); @@ -1607,17 +1612,20 @@ void ConvertTlsFile(uint8_t cert) { } char* tls_file = cert ? (char*)AmazonClientCert : (char*)AmazonPrivateKey; + printf("tls_file: %s\n", tls_file); RemoveSpace(tls_file); + printf("bin_buf\n"); uint32_t bin_len = decode_base64_length((unsigned char*)tls_file); + printf("bin_len: %d\n", bin_len); uint8_t *bin_buf = nullptr; if (bin_len > 0) { bin_buf = (uint8_t*) malloc(bin_len + 4); if (!bin_buf) { AddLog(LOG_LEVEL_ERROR, ALLOCATE_ERROR); free(spi_buffer); - return; + return false; } } @@ -1630,6 +1638,7 @@ void ConvertTlsFile(uint8_t cert) { bool save_file = false; // for ESP32, do we need to write file + printf("buffer ready\n"); if (!cert) { TlsEraseBuffer(spi_buffer); // Erase any previously stored data @@ -1639,7 +1648,7 @@ void ConvertTlsFile(uint8_t cert) { AddLog(LOG_LEVEL_INFO, PSTR("TLSKey: Certificate must be 32 bytes: %d."), bin_len); free(spi_buffer); free(bin_buf); - return; + return false; } tls_entry_t *entry = &tls_dir_write->entry[0]; entry->name = TLS_NAME_SKEY; @@ -1657,14 +1666,14 @@ void ConvertTlsFile(uint8_t cert) { AddLog(LOG_LEVEL_INFO, PSTR("TLSKey: cannot store Cert if no Key previously stored.")); free(spi_buffer); free(bin_buf); - return; + return false; } if (bin_len <= 256) { // Certificate lenght too short AddLog(LOG_LEVEL_INFO, PSTR("TLSKey: Certificate length too short: %d."), bin_len); free(spi_buffer); free(bin_buf); - return; + return false; } tls_entry_t *entry = &tls_dir_write->entry[1]; @@ -1683,6 +1692,7 @@ void ConvertTlsFile(uint8_t cert) { free(bin_buf); loadTlsDir(); // reload into memory any potential change + return true; } void CmndTlsKey(void) { @@ -1852,8 +1862,6 @@ const char HTTP_FORM_MQTT2[] PROGMEM = void HandleMqttConfiguration(void) { - if (!HttpCheckPriviledgedAccess()) { return; } - AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP D_CONFIGURE_MQTT)); if (Webserver->hasArg(F("save"))) { diff --git a/tasmota/xdrv_21_wemo_multi.ino b/tasmota/xdrv_21_wemo_multi.ino index e2e12c6b30b1..280770d8bb2f 100644 --- a/tasmota/xdrv_21_wemo_multi.ino +++ b/tasmota/xdrv_21_wemo_multi.ino @@ -429,33 +429,33 @@ void WemoRespondToMSearch(int echo_type) { bool Xdrv21(uint8_t function) { - bool result = false; - - if (TasmotaGlobal.devices_present && (EMUL_WEMO == Settings->flag2.emulation)) { - switch (function) { - case FUNC_LOOP: - for (uint32_t i = 1; i < numOfWemoSwitch; i++) { // Handle devices web server - wemoDevice[i]->HandleServerLoop(); - } - break; - case FUNC_WEB_ADD_HANDLER: -#ifdef USE_EMULATION_WEMO_DEBUG - AddLog(LOG_LEVEL_DEBUG, PSTR("WMO: Adding handlers for %d devices"), TasmotaGlobal.devices_present); -#endif - // For the first device use the current webserver, for the others.. create a new one listening on a different PortUdp - wemoDevice[numOfWemoSwitch] = new WemoSwitch(1, Webserver); - wemoDevice[numOfWemoSwitch]->RegisterHandlers(); - numOfWemoSwitch++; - - for (uint32_t i = 1; i < TasmotaGlobal.devices_present; i++) { - wemoDevice[numOfWemoSwitch] = new WemoSwitch(i + 1, 8080 + i); - wemoDevice[numOfWemoSwitch]->RegisterHandlers(); - numOfWemoSwitch++; - } - break; - } - } - return result; +// bool result = false; + +// if (TasmotaGlobal.devices_present && (EMUL_WEMO == Settings->flag2.emulation)) { +// switch (function) { +// case FUNC_LOOP: +// for (uint32_t i = 1; i < numOfWemoSwitch; i++) { // Handle devices web server +// wemoDevice[i]->HandleServerLoop(); +// } +// break; +// case FUNC_WEB_ADD_HANDLER: +// #ifdef USE_EMULATION_WEMO_DEBUG +// AddLog(LOG_LEVEL_DEBUG, PSTR("WMO: Adding handlers for %d devices"), TasmotaGlobal.devices_present); +// #endif +// // For the first device use the current webserver, for the others.. create a new one listening on a different PortUdp +// wemoDevice[numOfWemoSwitch] = new WemoSwitch(1, Webserver); +// wemoDevice[numOfWemoSwitch]->RegisterHandlers(); +// numOfWemoSwitch++; + +// for (uint32_t i = 1; i < TasmotaGlobal.devices_present; i++) { +// wemoDevice[numOfWemoSwitch] = new WemoSwitch(i + 1, 8080 + i); +// wemoDevice[numOfWemoSwitch]->RegisterHandlers(); +// numOfWemoSwitch++; +// } +// break; +// } +// } +// return result; } #endif // USE_WEBSERVER && USE_EMULATION && USE_EMULATION_WEMO \ No newline at end of file diff --git a/tasmota/xdrv_50_filesystem.ino b/tasmota/xdrv_50_filesystem.ino index bb3eb2c1b511..aea2530c0737 100644 --- a/tasmota/xdrv_50_filesystem.ino +++ b/tasmota/xdrv_50_filesystem.ino @@ -600,72 +600,72 @@ const char HTTP_EDITOR_FORM_END[] PROGMEM = #endif // #ifdef GUI_EDIT_FILE -void UfsDirectory(void) { - if (!HttpCheckPriviledgedAccess()) { return; } - - AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP D_MANAGE_FILE_SYSTEM)); - - uint8_t depth = 0; - - strcpy(ufs_path, "/"); - - if (Webserver->hasArg(F("download"))) { - String stmp = Webserver->arg(F("download")); - char *cp = (char*)stmp.c_str(); - if (UfsDownloadFile(cp)) { - // is directory - strcpy(ufs_path, cp); - } else { - return; - } - } - - if (Webserver->hasArg(F("dir"))) { - String stmp = Webserver->arg(F("dir")); - ufs_dir = atoi(stmp.c_str()); - if (ufs_dir == 1) { - dfsp = ufsp; - } else { - if (ffsp) { - dfsp = ffsp; - } - } - } - - if (Webserver->hasArg(F("delete"))) { - String stmp = Webserver->arg(F("delete")); - char *cp = (char*)stmp.c_str(); - dfsp->remove(cp); - } - - WSContentStart_P(PSTR(D_MANAGE_FILE_SYSTEM)); - WSContentSendStyle(); - WSContentSend_P(UFS_FORM_FILE_UPLOAD); - - char ts[FLOATSZ]; - dtostrfd((float)UfsInfo(0, ufs_dir == 2 ? 1:0) / 1000, 3, ts); - char fs[FLOATSZ]; - dtostrfd((float)UfsInfo(1, ufs_dir == 2 ? 1:0) / 1000, 3, fs); - WSContentSend_PD(UFS_FORM_FILE_UPGc, WebColor(COL_TEXT), ts, fs); - - if (ufs_dir) { - WSContentSend_P(UFS_FORM_FILE_UPGc1, (uint32_t)WiFi.localIP(), (ufs_dir == 1)?2:1, (ufs_dir == 1)?PSTR("SDCard"):PSTR("FlashFS")); - } - WSContentSend_P(UFS_FORM_FILE_UPGc2); - - WSContentSend_P(UFS_FORM_FILE_UPG, PSTR(D_SCRIPT_UPLOAD)); - - WSContentSend_P(UFS_FORM_SDC_DIRa); - if (ufs_type) { - UfsListDir(ufs_path, depth); - } - WSContentSend_P(UFS_FORM_SDC_DIRc); - WSContentSend_P(UFS_FORM_FILE_UPGb); - WSContentSpaceButton(BUTTON_MANAGEMENT); - WSContentStop(); - - Web.upload_file_type = UPL_UFSFILE; -} +// void UfsDirectory(void) { +// if (!HttpCheckPriviledgedAccess()) { return; } + +// AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP D_MANAGE_FILE_SYSTEM)); + +// uint8_t depth = 0; + +// strcpy(ufs_path, "/"); + +// if (Webserver->hasArg(F("download"))) { +// String stmp = Webserver->arg(F("download")); +// char *cp = (char*)stmp.c_str(); +// if (UfsDownloadFile(cp)) { +// // is directory +// strcpy(ufs_path, cp); +// } else { +// return; +// } +// } + +// if (Webserver->hasArg(F("dir"))) { +// String stmp = Webserver->arg(F("dir")); +// ufs_dir = atoi(stmp.c_str()); +// if (ufs_dir == 1) { +// dfsp = ufsp; +// } else { +// if (ffsp) { +// dfsp = ffsp; +// } +// } +// } + +// if (Webserver->hasArg(F("delete"))) { +// String stmp = Webserver->arg(F("delete")); +// char *cp = (char*)stmp.c_str(); +// dfsp->remove(cp); +// } + +// WSContentStart_P(PSTR(D_MANAGE_FILE_SYSTEM)); +// WSContentSendStyle(); +// WSContentSend_P(UFS_FORM_FILE_UPLOAD); + +// char ts[FLOATSZ]; +// dtostrfd((float)UfsInfo(0, ufs_dir == 2 ? 1:0) / 1000, 3, ts); +// char fs[FLOATSZ]; +// dtostrfd((float)UfsInfo(1, ufs_dir == 2 ? 1:0) / 1000, 3, fs); +// WSContentSend_PD(UFS_FORM_FILE_UPGc, WebColor(COL_TEXT), ts, fs); + +// if (ufs_dir) { +// WSContentSend_P(UFS_FORM_FILE_UPGc1, (uint32_t)WiFi.localIP(), (ufs_dir == 1)?2:1, (ufs_dir == 1)?PSTR("SDCard"):PSTR("FlashFS")); +// } +// WSContentSend_P(UFS_FORM_FILE_UPGc2); + +// WSContentSend_P(UFS_FORM_FILE_UPG, PSTR(D_SCRIPT_UPLOAD)); + +// WSContentSend_P(UFS_FORM_SDC_DIRa); +// if (ufs_type) { +// UfsListDir(ufs_path, depth); +// } +// WSContentSend_P(UFS_FORM_SDC_DIRc); +// WSContentSend_P(UFS_FORM_FILE_UPGb); +// WSContentSpaceButton(BUTTON_MANAGEMENT); +// WSContentStop(); + +// Web.upload_file_type = UPL_UFSFILE; +// } void UfsListDir(char *path, uint8_t depth) { char name[32]; @@ -1044,29 +1044,29 @@ bool Xdrv50(uint8_t function) { case FUNC_COMMAND: result = DecodeCommand(kUFSCommands, kUFSCommand); break; -#ifdef USE_WEBSERVER - case FUNC_WEB_ADD_MANAGEMENT_BUTTON: - if (ufs_type) { - if (XdrvMailbox.index) { - XdrvMailbox.index++; - } else { - WSContentSend_PD(UFS_WEB_DIR, PSTR(D_MANAGE_FILE_SYSTEM)); - } - } - break; - case FUNC_WEB_ADD_HANDLER: -// Webserver->on(F("/ufsd"), UfsDirectory); -// Webserver->on(F("/ufsu"), HTTP_GET, UfsDirectory); -// Webserver->on(F("/ufsu"), HTTP_POST,[](){Webserver->sendHeader(F("Location"),F("/ufsu"));Webserver->send(303);}, HandleUploadLoop); - Webserver->on("/ufsd", UfsDirectory); - Webserver->on("/ufsu", HTTP_GET, UfsDirectory); - Webserver->on("/ufsu", HTTP_POST,[](){Webserver->sendHeader(F("Location"),F("/ufsu"));Webserver->send(303);}, HandleUploadLoop); -#ifdef GUI_EDIT_FILE - Webserver->on("/ufse", HTTP_GET, UfsEditor); - Webserver->on("/ufse", HTTP_POST, UfsEditorUpload); -#endif - break; -#endif // USE_WEBSERVER +// #ifdef USE_WEBSERVER +// case FUNC_WEB_ADD_MANAGEMENT_BUTTON: +// if (ufs_type) { +// if (XdrvMailbox.index) { +// XdrvMailbox.index++; +// } else { +// WSContentSend_PD(UFS_WEB_DIR, PSTR(D_MANAGE_FILE_SYSTEM)); +// } +// } +// break; +// case FUNC_WEB_ADD_HANDLER: +// // Webserver->on(F("/ufsd"), UfsDirectory); +// // Webserver->on(F("/ufsu"), HTTP_GET, UfsDirectory); +// // Webserver->on(F("/ufsu"), HTTP_POST,[](){Webserver->sendHeader(F("Location"),F("/ufsu"));Webserver->send(303);}, HandleUploadLoop); +// Webserver->on("/ufsd", UfsDirectory); +// Webserver->on("/ufsu", HTTP_GET, UfsDirectory); +// Webserver->on("/ufsu", HTTP_POST,[](){Webserver->sendHeader(F("Location"),F("/ufsu"));Webserver->send(303);}, HandleUploadLoop); +// #ifdef GUI_EDIT_FILE +// Webserver->on("/ufse", HTTP_GET, UfsEditor); +// Webserver->on("/ufse", HTTP_POST, UfsEditorUpload); +// #endif +// break; +// #endif // USE_WEBSERVER } return result; }