From ae4780e05cc1faa424baf9beb4aa96a0d181f896 Mon Sep 17 00:00:00 2001 From: thiti yamsung Date: Tue, 23 Aug 2022 22:14:50 +0700 Subject: [PATCH 01/34] fix: It base64 error if use with WifiManager --- src/arduino_homekit_server.cpp | 2 +- src/arduino_homekit_server.h | 2 +- src/{base64.c => base64_util.c} | 2 +- src/{base64.h => base64_util.h} | 0 4 files changed, 3 insertions(+), 3 deletions(-) rename src/{base64.c => base64_util.c} (98%) rename src/{base64.h => base64_util.h} (100%) diff --git a/src/arduino_homekit_server.cpp b/src/arduino_homekit_server.cpp index 7121914..2cc6e5f 100644 --- a/src/arduino_homekit_server.cpp +++ b/src/arduino_homekit_server.cpp @@ -14,7 +14,7 @@ #include //wc_sha512 #include "constants.h" -#include "base64.h" +#include "base64_util.h" #include "pairing.h" #include "storage.h" #include "query_params.h" diff --git a/src/arduino_homekit_server.h b/src/arduino_homekit_server.h index ace3e01..3aa1f53 100644 --- a/src/arduino_homekit_server.h +++ b/src/arduino_homekit_server.h @@ -11,7 +11,7 @@ extern "C" { #endif #include "constants.h" -#include "base64.h" +#include "base64_util.h" #include "crypto.h" #include "pairing.h" #include "storage.h" diff --git a/src/base64.c b/src/base64_util.c similarity index 98% rename from src/base64.c rename to src/base64_util.c index 62bb36f..c7e8a38 100644 --- a/src/base64.c +++ b/src/base64_util.c @@ -1,4 +1,4 @@ -#include "base64.h" +#include "base64_util.h" static unsigned char base64_chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; diff --git a/src/base64.h b/src/base64_util.h similarity index 100% rename from src/base64.h rename to src/base64_util.h From 152730290307168165080b4b8ac9cc2adfa54cf1 Mon Sep 17 00:00:00 2001 From: thiti yamsung Date: Thu, 1 Sep 2022 18:24:45 +0700 Subject: [PATCH 02/34] fix: the device is not work after reconnect wifi --- src/arduino_homekit_server.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/arduino_homekit_server.cpp b/src/arduino_homekit_server.cpp index 7121914..0807288 100644 --- a/src/arduino_homekit_server.cpp +++ b/src/arduino_homekit_server.cpp @@ -3162,7 +3162,6 @@ void homekit_mdns_init(homekit_server_t *server) { } if (homekit_mdns_started) { - MDNS.close(); MDNS.begin(name->value.string_value, staIP); INFO("MDNS restart: %s, IP: %s", name->value.string_value, staIP.toString().c_str()); MDNS.announce(); From e1084acbf51b07f1c2c5c5c6f4202adb58b4f6b1 Mon Sep 17 00:00:00 2001 From: Paul Jordan Date: Sat, 19 Nov 2022 09:14:58 -0500 Subject: [PATCH 03/34] Remove logging --- src/homekit_debug.h | 40 +--------------------------------------- 1 file changed, 1 insertion(+), 39 deletions(-) diff --git a/src/homekit_debug.h b/src/homekit_debug.h index d28b475..1c7c9a7 100644 --- a/src/homekit_debug.h +++ b/src/homekit_debug.h @@ -18,51 +18,13 @@ typedef unsigned char byte; #define HOMEKIT_LOG_INFO 2 #define HOMEKIT_LOG_DEBUG 3 -#ifndef HOMEKIT_LOG_LEVEL -#define HOMEKIT_LOG_LEVEL HOMEKIT_LOG_INFO -#endif +#define HOMEKIT_LOG_LEVEL HOMEKIT_NO_LOG #define HOMEKIT_PRINTF XPGM_PRINTF -#if HOMEKIT_LOG_LEVEL >= HOMEKIT_LOG_DEBUG - -#define DEBUG(message, ...) HOMEKIT_PRINTF(">>> %s: " message "\n", __func__, ##__VA_ARGS__) -static uint32_t start_time = 0; -#define DEBUG_TIME_BEGIN() start_time=millis(); -#define DEBUG_TIME_END(func_name) HOMEKIT_PRINTF("### [%7d] %s took %6dms\n", millis(), func_name, (millis() - start_time)); -#define DEBUG_HEAP() DEBUG("Free heap: %d", system_get_free_heap_size()); - -#else - -#define DEBUG(message, ...) -#define DEBUG_TIME_BEGIN() -#define DEBUG_TIME_END(func_name) -#define DEBUG_HEAP() - -#endif - -#if HOMEKIT_LOG_LEVEL >= HOMEKIT_LOG_ERROR - -#define ERROR(message, ...) HOMEKIT_PRINTF("!!! [%7d] HomeKit: " message "\n", millis(), ##__VA_ARGS__) - -#else - -#define ERROR(message, ...) - -#endif #if HOMEKIT_LOG_LEVEL >= HOMEKIT_LOG_INFO -#define INFO(message, ...) HOMEKIT_PRINTF(">>> [%7d] HomeKit: " message "\n", millis(), ##__VA_ARGS__) -#define INFO_HEAP() INFO("Free heap: %d", system_get_free_heap_size()); - -#else - -#define INFO(message, ...) -#define INFO_HEAP() - -#endif - char *binary_to_string(const byte *data, size_t size); void print_binary(const char *prompt, const byte *data, size_t size); From 23a23060fd0109c0ffae7b476d0a22d79ead0064 Mon Sep 17 00:00:00 2001 From: Paul Jordan Date: Sat, 19 Nov 2022 09:26:49 -0500 Subject: [PATCH 04/34] Add debug back in, but make default "no log" --- src/homekit_debug.h | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/src/homekit_debug.h b/src/homekit_debug.h index 1c7c9a7..b09c631 100644 --- a/src/homekit_debug.h +++ b/src/homekit_debug.h @@ -18,13 +18,51 @@ typedef unsigned char byte; #define HOMEKIT_LOG_INFO 2 #define HOMEKIT_LOG_DEBUG 3 +#ifndef HOMEKIT_LOG_LEVEL #define HOMEKIT_LOG_LEVEL HOMEKIT_NO_LOG +#endif #define HOMEKIT_PRINTF XPGM_PRINTF +#if HOMEKIT_LOG_LEVEL >= HOMEKIT_LOG_DEBUG + +#define DEBUG(message, ...) HOMEKIT_PRINTF(">>> %s: " message "\n", __func__, ##__VA_ARGS__) +static uint32_t start_time = 0; +#define DEBUG_TIME_BEGIN() start_time=millis(); +#define DEBUG_TIME_END(func_name) HOMEKIT_PRINTF("### [%7d] %s took %6dms\n", millis(), func_name, (millis() - start_time)); +#define DEBUG_HEAP() DEBUG("Free heap: %d", system_get_free_heap_size()); + +#else + +#define DEBUG(message, ...) +#define DEBUG_TIME_BEGIN() +#define DEBUG_TIME_END(func_name) +#define DEBUG_HEAP() + +#endif + +#if HOMEKIT_LOG_LEVEL >= HOMEKIT_LOG_ERROR + +#define ERROR(message, ...) HOMEKIT_PRINTF("!!! [%7d] HomeKit: " message "\n", millis(), ##__VA_ARGS__) + +#else + +#define ERROR(message, ...) + +#endif #if HOMEKIT_LOG_LEVEL >= HOMEKIT_LOG_INFO +#define INFO(message, ...) HOMEKIT_PRINTF(">>> [%7d] HomeKit: " message "\n", millis(), ##__VA_ARGS__) +#define INFO_HEAP() INFO("Free heap: %d", system_get_free_heap_size()); + +#else + +#define INFO(message, ...) +#define INFO_HEAP() + +#endif + char *binary_to_string(const byte *data, size_t size); void print_binary(const char *prompt, const byte *data, size_t size); From f22ababf638d4b5c1048665d693bb1a788b6267a Mon Sep 17 00:00:00 2001 From: r0b0 Date: Sat, 25 Feb 2023 13:09:14 -0500 Subject: [PATCH 05/34] Fix complete annihilation of storage on new pair - Might fix #103, #139, #147, #184, #198 - Also adds changes by @ruleechen - Also adds changes by @thiti-y --- src/arduino_homekit_server.cpp | 77 +++++------------------ src/homekit_debug.h | 2 +- src/storage.c | 109 +++++++++++++++++++-------------- src/storage.h | 4 ++ 4 files changed, 84 insertions(+), 108 deletions(-) diff --git a/src/arduino_homekit_server.cpp b/src/arduino_homekit_server.cpp index 542fcaf..6dcbb9f 100644 --- a/src/arduino_homekit_server.cpp +++ b/src/arduino_homekit_server.cpp @@ -524,6 +524,10 @@ void write(client_context_t *context, byte *data, int data_size) { CLIENT_ERROR(context, "The socket is null! (or is closed)"); return; } + if (context->disconnect) { + context->error_write = true; + return; + } if (context->error_write) { CLIENT_ERROR(context, "Abort write data since error_write."); return; @@ -531,20 +535,10 @@ void write(client_context_t *context, byte *data, int data_size) { int write_size = context->socket->write(data, data_size); CLIENT_DEBUG(context, "Sending data of size %d", data_size); if (write_size != data_size) { - CLIENT_ERROR(context, "socket.write, data_size=%d, write_size=%d", data_size, write_size); context->error_write = true; - // Error write when : - // 1. remote client is disconnected - // 2. data_size is larger than the tcp internal send buffer - // But We has limited the data_size to 538, and TCP_SND_BUF = 1072. (See the comments on HOMEKIT_JSONBUFFER_SIZE) - // So we believe here is disconnected. - context->disconnect = true; - homekit_server_close_client(context->server, context); - // We consider the socket is 'closed' when error in writing (eg. the remote client is disconnected, NO tcp ack receive). - // Closing the socket causes memory-leak if some data has not been sent (the write_buffer did not free) - // To fix this memory-leak, add tcp_abandon(_pcb, 0); in ClientContext.h of ESP8266WiFi-library. + context->socket->keepAlive(1, 1, 1); // fast disconnected internally in 1 second. + CLIENT_ERROR(context, "socket.write, data_size=%d, write_size=%d", data_size, write_size); } - } int client_send_encrypted_(client_context_t *context, @@ -2699,9 +2693,6 @@ void homekit_server_on_reset(client_context_t *context) { homekit_server_reset(); send_204_response(context); - - //vTaskDelay(3000 / portTICK_PERIOD_MS); - homekit_system_restart(); } @@ -3141,27 +3132,30 @@ void homekit_mdns_init(homekit_server_t *server) { homekit_accessory_t *accessory = server->config->accessories[0]; homekit_service_t *accessory_info = homekit_service_by_type(accessory, - HOMEKIT_SERVICE_ACCESSORY_INFORMATION); + HOMEKIT_SERVICE_ACCESSORY_INFORMATION); if (!accessory_info) { ERROR("Invalid accessory declaration: no Accessory Information service"); return; } homekit_characteristic_t *name = homekit_service_characteristic_by_type(accessory_info, - HOMEKIT_CHARACTERISTIC_NAME); + HOMEKIT_CHARACTERISTIC_NAME); + if (!name) { ERROR("Invalid accessory declaration: " "no Name characteristic in AccessoryInfo service"); return; } - + homekit_characteristic_t *model = homekit_service_characteristic_by_type(accessory_info, - HOMEKIT_CHARACTERISTIC_MODEL); + HOMEKIT_CHARACTERISTIC_MODEL); + if (!model) { ERROR("Invalid accessory declaration: " "no Model characteristic in AccessoryInfo service"); return; } if (homekit_mdns_started) { + // MDNS.close(); MDNS.begin(name->value.string_value, staIP); INFO("MDNS restart: %s, IP: %s", name->value.string_value, staIP.toString().c_str()); MDNS.announce(); @@ -3175,7 +3169,7 @@ void homekit_mdns_init(homekit_server_t *server) { INFO("MDNS begin: %s, IP: %s", name->value.string_value, staIP.toString().c_str()); MDNSResponder::hMDNSService mdns_service = MDNS.addService(name->value.string_value, - HOMEKIT_MDNS_SERVICE, HOMEKIT_MDNS_PROTO, HOMEKIT_SERVER_PORT); + HOMEKIT_MDNS_SERVICE, HOMEKIT_MDNS_PROTO, HOMEKIT_SERVER_PORT); // Set a service specific callback for dynamic service TXT items. // The callback is called, whenever service TXT items are needed for the given service. MDNS.setDynamicServiceTxtCallback(mdns_service, @@ -3206,31 +3200,6 @@ void homekit_mdns_init(homekit_server_t *server) { //MDNS.addServiceTxt(HAP_SERVICE, HOMEKIT_MDNS_PROTO, "sf", (server->paired) ? "0" : "1"); MDNS.addServiceTxt(mdns_service, "ci", String(server->config->category).c_str()); - /* - // accessory model name (required) - homekit_mdns_add_txt("md", "%s", model->value.string_value); - // protocol version (required) - homekit_mdns_add_txt("pv", "1.0"); - // device ID (required) - // should be in format XX:XX:XX:XX:XX:XX, otherwise devices will ignore it - homekit_mdns_add_txt("id", "%s", server->accessory_id); - // current configuration number (required) - homekit_mdns_add_txt("c#", "%d", server->config->config_number); - // current state number (required) - homekit_mdns_add_txt("s#", "1"); - // feature flags (required if non-zero) - // bit 0 - supports HAP pairing. required for all HomeKit accessories - // bits 1-7 - reserved - homekit_mdns_add_txt("ff", "0"); - // status flags - // bit 0 - not paired - // bit 1 - not configured to join WiFi - // bit 2 - problem detected on accessory - // bits 3-7 - reserved - homekit_mdns_add_txt("sf", "%d", (server->paired) ? 0 : 1); - // accessory category identifier - homekit_mdns_add_txt("ci", "%d", server->config->category);*/ - if (server->config->setupId) { DEBUG("Accessory Setup ID = %s", server->config->setupId); @@ -3254,8 +3223,6 @@ void homekit_mdns_init(homekit_server_t *server) { MDNS.announce(); MDNS.update(); homekit_mdns_started = true; - //INFO("MDNS ok! Open your \"Home\" app, click \"Add or Scan Accessory\"" - // " and \"I Don't Have a Code\". \nThis Accessory will show on your iOS device."); } // Used to update the config_number ("c#" value of Bonjour) @@ -3350,19 +3317,9 @@ void homekit_server_init(homekit_server_config_t *config) { //homekit_server_task(server); INFO("Starting server"); - int r = homekit_storage_init(); - if (r == 0) { - r = homekit_storage_load_accessory_id(server->accessory_id); - - if (!r) - r = homekit_storage_load_accessory_key(&server->accessory_key); - } - - if (r) { - if (r < 0) { - INFO("Resetting HomeKit storage"); - homekit_storage_reset(); - } + if (homekit_storage_init() != 0 || + homekit_storage_load_accessory_id(server->accessory_id) != 0 || + homekit_storage_load_accessory_key(&server->accessory_key) != 0) { homekit_accessory_id_generate(server->accessory_id); homekit_storage_save_accessory_id(server->accessory_id); diff --git a/src/homekit_debug.h b/src/homekit_debug.h index b09c631..bf2b840 100644 --- a/src/homekit_debug.h +++ b/src/homekit_debug.h @@ -19,7 +19,7 @@ typedef unsigned char byte; #define HOMEKIT_LOG_DEBUG 3 #ifndef HOMEKIT_LOG_LEVEL -#define HOMEKIT_LOG_LEVEL HOMEKIT_NO_LOG +#define HOMEKIT_LOG_LEVEL HOMEKIT_LOG_DEBUG #endif #define HOMEKIT_PRINTF XPGM_PRINTF diff --git a/src/storage.c b/src/storage.c index d6f69a7..5c1584e 100644 --- a/src/storage.c +++ b/src/storage.c @@ -78,11 +78,11 @@ extern uint32_t _SPIFFS_start; //See spiffs_api.h #define STORAGE_DEBUG(message, ...) //printf("*** [Storage] %s: " message "\n", __func__, ##__VA_ARGS__) -const char magic1[] = "HAP"; +const char hap_magic[] = "HAP"; // TODO: figure out alignment issues typedef struct { - char magic[sizeof(magic1)]; + char magic[sizeof(hap_magic)]; byte permissions; char device_id[DEVICE_ID_SIZE]; byte device_public_key[32]; @@ -90,47 +90,50 @@ typedef struct { byte _reserved[7]; // align record to be 80 bytes } pairing_data_t; +bool homekit_storage_magic_valid() { + char magic_test[sizeof(hap_magic)]; + bzero(magic_test, sizeof(magic_test)); -int homekit_storage_init() { + if (!spiflash_read(MAGIC_ADDR, (byte *)magic_test, sizeof(magic_test))) { + ERROR("Failed to read HomeKit storage magic"); + return false; + } + return (memcmp(magic_test, hap_magic, sizeof(hap_magic)) == 0); +} - STORAGE_DEBUG("EEPROM max: %d B", SPI_FLASH_SEC_SIZE);//4096B - STORAGE_DEBUG("Pairing_data size: %d ", (sizeof(pairing_data_t)));//80B - STORAGE_DEBUG("MAX pairing count: %d ", MAX_PAIRINGS);//16 - STORAGE_DEBUG("_EEPROM_start: 0x%x (%u)", - HOMEKIT_EEPROM_PHYS_ADDR, HOMEKIT_EEPROM_PHYS_ADDR); - STORAGE_DEBUG("_SPIFFS_start: 0x%x (%u)", - HOMEKIT_SPIFFS_PHYS_ADDR, HOMEKIT_SPIFFS_PHYS_ADDR); +bool homekit_storage_set_magic() { + if (!spiflash_write(MAGIC_ADDR, (byte *)hap_magic, sizeof(hap_magic))) { + ERROR("Failed to write HomeKit storage magic"); + return false; + } + return true; +} - char magic[sizeof(magic1)]; - memset(magic, 0, sizeof(magic)); +int homekit_storage_init() { - if (!spiflash_read(MAGIC_ADDR, (byte *)magic, sizeof(magic))) { - ERROR("Failed to read HomeKit storage magic"); - } + STORAGE_DEBUG("EEPROM max: %d B", SPI_FLASH_SEC_SIZE);//4096B + STORAGE_DEBUG("Pairing_data size: %d ", (sizeof(pairing_data_t)));//80B + STORAGE_DEBUG("MAX pairing count: %d ", MAX_PAIRINGS);//16 + STORAGE_DEBUG("_EEPROM_start: 0x%x (%u)", + HOMEKIT_EEPROM_PHYS_ADDR, HOMEKIT_EEPROM_PHYS_ADDR); + STORAGE_DEBUG("_SPIFFS_start: 0x%x (%u)", + HOMEKIT_SPIFFS_PHYS_ADDR, HOMEKIT_SPIFFS_PHYS_ADDR); - if (strncmp(magic, magic1, sizeof(magic1))) { + if (!homekit_storage_magic_valid()) { INFO("Formatting HomeKit storage at 0x%x", STORAGE_BASE_ADDR); - if (!spiflash_erase_sector(STORAGE_BASE_ADDR)) { + if (!spiflash_erase_sector(STORAGE_BASE_ADDR) || !homekit_storage_set_magic()) { ERROR("Failed to erase HomeKit storage"); - return -1; + return -1; // Fail case } - - strncpy(magic, magic1, sizeof(magic)); - if (!spiflash_write(MAGIC_ADDR, (byte *)magic, sizeof(magic))) { - ERROR("Failed to write HomeKit storage magic"); - return -1; - } - - return 1; + return 1; // Wasn't valid, is now } - - return 0; + return 0; // Was valid } int homekit_storage_reset() { - byte blank[sizeof(magic1)]; - memset(blank, 0, sizeof(blank)); + byte blank[sizeof(hap_magic)]; + bzero(blank, sizeof(blank)); if (!spiflash_write(MAGIC_ADDR, blank, sizeof(blank))) { ERROR("Failed to reset HomeKit storage"); @@ -140,6 +143,18 @@ int homekit_storage_reset() { return homekit_storage_init(); } +int homekit_storage_reset_pairing_data() { + + byte blank[sizeof(pairing_data_t) * MAX_PAIRINGS]; + bzero(blank,sizeof(blank)); + + INFO("Formatting HomeKit storage at 0x%x", PAIRINGS_OFFSET); + if (!spiflash_write(PAIRINGS_OFFSET, blank, sizeof(blank))) { + ERROR("Failed to erase HomeKit pairing storage"); + return -1; // Fail case + } + return 0; +} void homekit_storage_save_accessory_id(const char *accessory_id) { if (!spiflash_write(ACCESSORY_ID_ADDR, (byte *)accessory_id, ACCESSORY_ID_SIZE)) { @@ -209,7 +224,7 @@ bool homekit_storage_can_add_pairing() { pairing_data_t data; for (int i=0; imagic, magic1, sizeof(magic1))) { + if (!memcmp(pairing_data->magic, hap_magic, sizeof(hap_magic))) { if (i != next_pairing_idx) { memcpy(&data[PAIRINGS_ADDR + sizeof(pairing_data_t)*next_pairing_idx], pairing_data, sizeof(*pairing_data)); @@ -241,7 +256,7 @@ static int compact_data() { return 0; } - if (homekit_storage_reset()) { + if (homekit_storage_reset_pairing_data()) { ERROR("Failed to compact HomeKit storage: error resetting flash"); free(data); return -1; @@ -291,10 +306,10 @@ int homekit_storage_add_pairing(const char *device_id, const ed25519_key *device pairing_data_t data; - memset(&data, 0, sizeof(data)); - strncpy(data.magic, magic1, sizeof(data.magic)); + bzero(&data, sizeof(data)); + memcpy(data.magic, hap_magic, sizeof(data.magic)); data.permissions = permissions; - strncpy(data.device_id, device_id, sizeof(data.device_id)); + memcpy(data.device_id, device_id, sizeof(data.device_id)); size_t device_public_key_size = sizeof(data.device_public_key); int r = crypto_ed25519_export_public_key( device_key, data.device_public_key, &device_public_key_size @@ -317,10 +332,10 @@ int homekit_storage_update_pairing(const char *device_id, byte permissions) { pairing_data_t data; for (int i=0; idevice_key); int r = crypto_ed25519_import_public_key(&pairing->device_key, data.device_public_key, sizeof(data.device_public_key)); if (r) { @@ -389,7 +404,7 @@ int homekit_storage_find_pairing(const char *device_id, pairing_t *pairing) { } pairing->id = i; - strncpy(pairing->device_id, data.device_id, DEVICE_ID_SIZE); + memcpy(pairing->device_id, data.device_id, DEVICE_ID_SIZE); pairing->device_id[DEVICE_ID_SIZE] = 0; pairing->permissions = data.permissions; @@ -416,7 +431,7 @@ int homekit_storage_next_pairing(pairing_iterator_t *it, pairing_t *pairing) { int id = it->idx++; spiflash_read(PAIRINGS_ADDR + sizeof(data)*id, (byte *)&data, sizeof(data)); - if (!strncmp(data.magic, magic1, sizeof(data.magic))) { + if (!memcmp(data.magic, hap_magic, sizeof(data.magic))) { crypto_ed25519_init(&pairing->device_key); int r = crypto_ed25519_import_public_key(&pairing->device_key, data.device_public_key, sizeof(data.device_public_key)); if (r) { @@ -425,7 +440,7 @@ int homekit_storage_next_pairing(pairing_iterator_t *it, pairing_t *pairing) { } pairing->id = id; - strncpy(pairing->device_id, data.device_id, DEVICE_ID_SIZE); + memcpy(pairing->device_id, data.device_id, DEVICE_ID_SIZE); pairing->device_id[DEVICE_ID_SIZE] = 0; pairing->permissions = data.permissions; diff --git a/src/storage.h b/src/storage.h index 4ea193f..753768d 100644 --- a/src/storage.h +++ b/src/storage.h @@ -9,7 +9,11 @@ extern "C" { #include "pairing.h" +bool homekit_storage_magic_valid(); +bool homekit_storage_set_magic(); + int homekit_storage_reset(); +int homekit_storage_reset_pairing_data(); int homekit_storage_init(); From d803adfa9e1ddd62c5cb588511bcb9ffb67541ee Mon Sep 17 00:00:00 2001 From: r0b0 Date: Sat, 25 Feb 2023 14:16:17 -0500 Subject: [PATCH 06/34] Fix incorrect access of global var --- src/homekit_debug.h | 2 +- src/storage.c | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/homekit_debug.h b/src/homekit_debug.h index bf2b840..b09c631 100644 --- a/src/homekit_debug.h +++ b/src/homekit_debug.h @@ -19,7 +19,7 @@ typedef unsigned char byte; #define HOMEKIT_LOG_DEBUG 3 #ifndef HOMEKIT_LOG_LEVEL -#define HOMEKIT_LOG_LEVEL HOMEKIT_LOG_DEBUG +#define HOMEKIT_LOG_LEVEL HOMEKIT_NO_LOG #endif #define HOMEKIT_PRINTF XPGM_PRINTF diff --git a/src/storage.c b/src/storage.c index 5c1584e..40b893c 100644 --- a/src/storage.c +++ b/src/storage.c @@ -102,7 +102,10 @@ bool homekit_storage_magic_valid() { } bool homekit_storage_set_magic() { - if (!spiflash_write(MAGIC_ADDR, (byte *)hap_magic, sizeof(hap_magic))) { + char magic[sizeof(hap_magic)]; + memcpy(magic, hap_magic, sizeof(magic)); + + if (!spiflash_write(MAGIC_ADDR, (byte *)magic, sizeof(magic))) { ERROR("Failed to write HomeKit storage magic"); return false; } From d108ac65be535f91c6f7bc7442c6d812b63ccaf8 Mon Sep 17 00:00:00 2001 From: Craig Furter Date: Sun, 16 Jul 2023 23:28:45 +1200 Subject: [PATCH 07/34] Corrected pairing address for resets. --- src/storage.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/storage.c b/src/storage.c index 40b893c..2f1fdf6 100644 --- a/src/storage.c +++ b/src/storage.c @@ -152,7 +152,7 @@ int homekit_storage_reset_pairing_data() { bzero(blank,sizeof(blank)); INFO("Formatting HomeKit storage at 0x%x", PAIRINGS_OFFSET); - if (!spiflash_write(PAIRINGS_OFFSET, blank, sizeof(blank))) { + if (!spiflash_write(PAIRINGS_ADDR, blank, sizeof(blank))) { ERROR("Failed to erase HomeKit pairing storage"); return -1; // Fail case } From 631944071be7f7f4fb2828bc879c974df3952f8e Mon Sep 17 00:00:00 2001 From: Craig Furter Date: Mon, 17 Jul 2023 01:45:38 +1200 Subject: [PATCH 08/34] Fixed "empty" block logic. --- src/storage.c | 89 +++++++++++++++++++++++++++------------------------ 1 file changed, 48 insertions(+), 41 deletions(-) diff --git a/src/storage.c b/src/storage.c index 2f1fdf6..2eb3e89 100644 --- a/src/storage.c +++ b/src/storage.c @@ -76,7 +76,7 @@ extern uint32_t _SPIFFS_start; //See spiffs_api.h #define ACCESSORY_KEY_SIZE 64 -#define STORAGE_DEBUG(message, ...) //printf("*** [Storage] %s: " message "\n", __func__, ##__VA_ARGS__) +#define STORAGE_DEBUG(message, ...) printf("*** [Storage] %s: " message "\n", __func__, ##__VA_ARGS__) const char hap_magic[] = "HAP"; @@ -94,7 +94,7 @@ bool homekit_storage_magic_valid() { char magic_test[sizeof(hap_magic)]; bzero(magic_test, sizeof(magic_test)); - if (!spiflash_read(MAGIC_ADDR, (byte *)magic_test, sizeof(magic_test))) { + if (!spiflash_read(MAGIC_ADDR, (uint32 *)magic_test, sizeof(magic_test))) { ERROR("Failed to read HomeKit storage magic"); return false; } @@ -105,7 +105,7 @@ bool homekit_storage_set_magic() { char magic[sizeof(hap_magic)]; memcpy(magic, hap_magic, sizeof(magic)); - if (!spiflash_write(MAGIC_ADDR, (byte *)magic, sizeof(magic))) { + if (!spiflash_write(MAGIC_ADDR, (uint32 *)magic, sizeof(magic))) { ERROR("Failed to write HomeKit storage magic"); return false; } @@ -130,6 +130,21 @@ int homekit_storage_init() { } return 1; // Wasn't valid, is now } + + pairing_data_t data; + int paired = 0; + for (int i=0; iidx < MAX_PAIRINGS) { int id = it->idx++; - spiflash_read(PAIRINGS_ADDR + sizeof(data)*id, (byte *)&data, sizeof(data)); + spiflash_read(PAIRINGS_ADDR + sizeof(data)*id, (uint32 *)&data, sizeof(data)); if (!memcmp(data.magic, hap_magic, sizeof(data.magic))) { crypto_ed25519_init(&pairing->device_key); int r = crypto_ed25519_import_public_key(&pairing->device_key, data.device_public_key, sizeof(data.device_public_key)); From e31e2c95d08dd26ab100bb70c41ae18459c53695 Mon Sep 17 00:00:00 2001 From: Craig Furter Date: Mon, 17 Jul 2023 02:41:09 +1200 Subject: [PATCH 09/34] Enum fix. --- src/arduino_homekit_server.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/arduino_homekit_server.cpp b/src/arduino_homekit_server.cpp index 6dcbb9f..8d96f12 100644 --- a/src/arduino_homekit_server.cpp +++ b/src/arduino_homekit_server.cpp @@ -2329,7 +2329,7 @@ HAPStatus process_characteristics_update(const cJSON *j_ch, client_context_t *co cJSON *j_events = cJSON_GetObjectItem(j_ch, "ev"); if (j_events) { - if (!(ch->permissions && homekit_permissions_notify)) { + if (!(ch->permissions & homekit_permissions_notify)) { CLIENT_ERROR(context, "Failed to set notification state for %d.%d: " "notifications are not supported", aid, iid); From 34232d3ebd3771850ec2038f41897c3e7d58bf2b Mon Sep 17 00:00:00 2001 From: Craig Furter Date: Wed, 19 Jul 2023 23:49:29 +1200 Subject: [PATCH 10/34] Fixed alignment issues. --- src/arduino_homekit_server.cpp | 39 ++--- src/storage.c | 289 ++++++++++++++++++--------------- src/storage.h | 2 +- 3 files changed, 179 insertions(+), 151 deletions(-) diff --git a/src/arduino_homekit_server.cpp b/src/arduino_homekit_server.cpp index 8d96f12..117179a 100644 --- a/src/arduino_homekit_server.cpp +++ b/src/arduino_homekit_server.cpp @@ -45,7 +45,7 @@ #define HOMEKIT_SOCKET_KEEPALIVE_INTERVAL_SEC 30 //const int maxpkt = 4; /* Drop connection after 4 probes without response */ #define HOMEKIT_SOCKET_KEEPALIVE_IDLE_COUNT 4 -// if 180 + 30 * 4 = 300 sec without socket response, disconected it. +// if 180 + 30 * 4 = 300 sec without socket response, disconnected it. // WiFiClient can not write big buff once. // TCP_SND_BUF = (2 * TCP_MSS) = 1072. See lwipopts.h @@ -118,10 +118,10 @@ void server_free(homekit_server_t *server) { } void tlv_debug(const tlv_values_t *values) { - DEBUG("Got following TLV values:"); + printf("Got following TLV values:\n"); for (tlv_t *t = values->head; t; t = t->next) { char *escaped_payload = binary_to_string(t->value, t->size); - DEBUG("Type %d value (%d bytes): %s", t->type, t->size, escaped_payload); + printf("\tType %d value (%d bytes): %s\n", t->type, t->size, escaped_payload); free(escaped_payload); } } @@ -562,7 +562,7 @@ int client_send_encrypted_(client_context_t *context, memset(nonce, 0, sizeof(nonce)); byte encrypted[1024 + 18]; - int payload_offset = 0; + uint payload_offset = 0; while (payload_offset < size) { size_t chunk_size = size - payload_offset; @@ -1879,7 +1879,7 @@ void homekit_server_on_get_characteristics(client_context_t *context) { query_param_t *qp = context->endpoint_params; while (qp) { - CLIENT_DEBUG(context, "Query paramter %s = %s", qp->name, qp->value); + CLIENT_DEBUG(context, "Query parameter %s = %s", qp->name, qp->value); qp = qp->next; } @@ -2629,6 +2629,7 @@ void homekit_server_on_pairings(client_context_t *context, const byte *data, siz INFO("Last admin pairing was removed, enabling pair setup"); context->server->paired = false; //homekit_setup_mdns(context->server); + homekit_storage_reset_pairing_data(); } } } @@ -2760,7 +2761,7 @@ int homekit_server_on_url(http_parser *parser, const char *data, size_t length) } int homekit_server_on_body(http_parser *parser, const char *data, size_t length) { - DEBUG("http_parser lenght=%d", length); + DEBUG("http_parser length=%d", length); client_context_t *context = (client_context_t*) parser->data; context->body = (char*) realloc(context->body, context->body_length + length + 1); memcpy(context->body + context->body_length, data, length); @@ -2888,7 +2889,7 @@ void homekit_client_process(client_context_t *context) { } return; } - CLIENT_DEBUG(context, "Got %d incomming data, encrypted is %s", + CLIENT_DEBUG(context, "Got %d incoming data, encrypted is %s", data_len, context->encrypted ? "true" : "false"); byte *payload = (byte*) context->data; size_t payload_size = (size_t) data_len; @@ -2942,7 +2943,7 @@ void homekit_server_close_client(homekit_server_t *server, client_context_t *con if (context->socket) { context->socket->stop(); - CLIENT_DEBUG(context, "The sockect is stopped"); + CLIENT_DEBUG(context, "The socket is stopped"); delete context->socket; context->socket = nullptr; } @@ -2979,7 +2980,7 @@ client_context_t* homekit_server_accept_client(homekit_server_t *server) { WiFiClient *wifiClient = nullptr; if (server->wifi_server->hasClient()) { - wifiClient = new WiFiClient(server->wifi_server->available()); + wifiClient = new WiFiClient(server->wifi_server->accept()); if (server->nfds >= HOMEKIT_MAX_CLIENTS) { INFO("No more room for client connections (max %d)", HOMEKIT_MAX_CLIENTS); wifiClient->stop(); @@ -2990,7 +2991,8 @@ client_context_t* homekit_server_accept_client(homekit_server_t *server) { return NULL; } - INFO("Got new client: local %s:%d, remote %s:%d", + INFO("Got new client %d: local %s:%d, remote %s:%d", + wifiClient, wifiClient->localIP().toString().c_str(), wifiClient->localPort(), wifiClient->remoteIP().toString().c_str(), wifiClient->remotePort()); @@ -3018,7 +3020,7 @@ client_context_t* homekit_server_accept_client(homekit_server_t *server) { void homekit_server_process_notifications(homekit_server_t *server) { client_context_t *context = server->clients; // 把characteristic_event_t拼接成client_event_t链表 - // 按照Apple的规定,Nofiy消息需合并发送 + // 按照Apple的规定,Notify消息需合并发送 while (context) { if (context->step != HOMEKIT_CLIENT_STEP_PAIR_VERIFY_2OF2) { // Do not send event when the client is not verify over. @@ -3114,7 +3116,7 @@ void homekit_server_process(homekit_server_t *server) { } //===================================================== -// Arduino ESP8266 MDNS: call this funciton only once when WiFi STA is connected! +// Arduino ESP8266 MDNS: call this function only once when WiFi STA is connected! //===================================================== bool homekit_mdns_started = false; @@ -3145,7 +3147,7 @@ void homekit_mdns_init(homekit_server_t *server) { ERROR("Invalid accessory declaration: " "no Name characteristic in AccessoryInfo service"); return; } - + homekit_characteristic_t *model = homekit_service_characteristic_by_type(accessory_info, HOMEKIT_CHARACTERISTIC_MODEL); @@ -3215,7 +3217,6 @@ void homekit_mdns_init(homekit_server_t *server) { unsigned char encodedHash[9]; memset(encodedHash, 0, sizeof(encodedHash)); - word32 len = sizeof(encodedHash); base64_encode_((const unsigned char*) shaHash, 4, encodedHash); MDNS.addServiceTxt(mdns_service, "sh", (char*) encodedHash); } @@ -3317,7 +3318,7 @@ void homekit_server_init(homekit_server_config_t *config) { //homekit_server_task(server); INFO("Starting server"); - if (homekit_storage_init() != 0 || + if (homekit_storage_init(false) != 0 || homekit_storage_load_accessory_id(server->accessory_id) != 0 || homekit_storage_load_accessory_key(&server->accessory_key) != 0) { @@ -3399,11 +3400,11 @@ int homekit_get_setup_uri(const homekit_server_config_t *config, char *buffer, s if (!config->password) return -1; - // TODO: validate password in case it is run beffore server is started + // TODO: validate password in case it is run before server is started if (!config->setupId) return -1; - // TODO: validate setupID in case it is run beffore server is started + // TODO: validate setupID in case it is run before server is started homekit_accessory_t *accessory = homekit_accessory_by_id(config->accessories, 1); if (!accessory) @@ -3445,8 +3446,8 @@ int homekit_get_setup_uri(const homekit_server_config_t *config, char *buffer, s return 0; } -// Pre-initialize the pairing_context used in Pair-Setep 1/3 -// For avoiding timeout caused sockect disconnection from iOS device. +// Pre-initialize the pairing_context used in Pair-Setup 1/3 +// For avoiding timeout caused socket disconnection from iOS device. bool arduino_homekit_preinit(homekit_server_t *server) { if (saved_preinit_pairing_context != nullptr) { return true; diff --git a/src/storage.c b/src/storage.c index 2eb3e89..48b3583 100644 --- a/src/storage.c +++ b/src/storage.c @@ -9,33 +9,8 @@ #include "crypto.h" #include "homekit_debug.h" -//#include "c_types.h" -//#include "ets_sys.h" -//#include "os_type.h" -//#include "osapi.h" -//#include "spi_flash.h" -//#include "spi_flash_geometry.h" -//#include "FS.h" -//#include "spiffs_api.h" - -// ESP82666 spi_flash_geometry.h -// FLASH_SECTOR_SIZE 0x1000 = 4096B -// EEPROM use _sector = _EEPROM_start -// the "_EEPROM_start" value is provided in tools/sdk/ld/eagle.flash.**.ld - -// We use the EEPROM address for this storage.c in Arduino environment -// EEPROM = one SPI_FLASH_SEC_SIZE = 0x1000 = 4096B -// SPI_FLASH_SEC_SIZE = 4096B -// sizeof(pairing_data_t) = 80B -// MAX_PAIRINGS = 16 -// PAIRINGS_OFFSET = 128(address) -// so max use address of (128 + 80 * 16) = 1408 B - -// This storage use [0, 1408) of EEPROM, leave [1408, 4096) for user to use safely. -// Leave the FS(file system) for user to use freely. - /* - +[...] See https://arduino-esp8266.readthedocs.io/en/2.6.3/filesystem.html https://arduino-esp8266.readthedocs.io/en/2.6.3/libraries.html#eeprom @@ -46,7 +21,13 @@ The following diagram illustrates flash layout used in Arduino environment: |--------------|-------|---------------|--|--|--|--|--| ^ ^ ^ ^ ^ Sketch OTA update File system EEPROM WiFi config (SDK) +[...] +We use the EEPROM region os the flash. however, we can only write once to erased sections. +Alignment needs to be a factor of 4 and blocks written cannot be smaller than 4 bytes else +the ESP has a fit. + +ref: https://docs.ai-thinker.com/_media/esp8266/docs/espressif_iot_flash_rw_operation_en.pdf */ #pragma GCC diagnostic ignored "-Wunused-value" @@ -72,29 +53,32 @@ extern uint32_t _SPIFFS_start; //See spiffs_api.h #define ACCESSORY_KEY_ADDR (STORAGE_BASE_ADDR + ACCESSORY_KEY_OFFSET) #define PAIRINGS_ADDR (STORAGE_BASE_ADDR + PAIRINGS_OFFSET) -#define MAX_PAIRINGS 16 - -#define ACCESSORY_KEY_SIZE 64 +#define MAX_PAIRINGS 16 +#define ACCESSORY_KEY_SIZE 64 +#ifdef HOMEKIT_DEBUG #define STORAGE_DEBUG(message, ...) printf("*** [Storage] %s: " message "\n", __func__, ##__VA_ARGS__) +#else +#define STORAGE_DEBUG(message, ...) +#endif const char hap_magic[] = "HAP"; -// TODO: figure out alignment issues typedef struct { char magic[sizeof(hap_magic)]; byte permissions; char device_id[DEVICE_ID_SIZE]; byte device_public_key[32]; - byte _reserved[7]; // align record to be 80 bytes + byte _reserved[6]; // align record to be 80 bytes + byte active; } pairing_data_t; bool homekit_storage_magic_valid() { char magic_test[sizeof(hap_magic)]; bzero(magic_test, sizeof(magic_test)); - if (!spiflash_read(MAGIC_ADDR, (uint32 *)magic_test, sizeof(magic_test))) { + if (!spiflash_read(MAGIC_ADDR, (uint32_t *) magic_test, sizeof(magic_test))) { ERROR("Failed to read HomeKit storage magic"); return false; } @@ -105,94 +89,137 @@ bool homekit_storage_set_magic() { char magic[sizeof(hap_magic)]; memcpy(magic, hap_magic, sizeof(magic)); - if (!spiflash_write(MAGIC_ADDR, (uint32 *)magic, sizeof(magic))) { + if (!spiflash_write(MAGIC_ADDR, (uint32_t *) magic, sizeof(magic))) { ERROR("Failed to write HomeKit storage magic"); return false; } return true; } -int homekit_storage_init() { +#ifdef HOMEKIT_DEBUG +static char buf[128]; +static void dump_pairing_data(pairing_data_t *data) { + if (memcmp(data->magic, hap_magic, sizeof(hap_magic)) || !data->active) return; + + char *t = buf; + t += sprintf(t, "device_id: %s", data->permissions & pairing_permissions_admin ? "(admin) " : ""); + for (int i = 0; i < sizeof(data->device_id); i++) { + t += sprintf(t, "%c", data->device_id[i] > 31 && data->device_id[i] < 128 ? data->device_id[i] : '.'); + } + + INFO("%s", buf); +} + +void dump_storage() +{ + byte *__buf = malloc(PAIRINGS_OFFSET + (MAX_PAIRINGS * sizeof(pairing_data_t))); + if (!spiflash_read(STORAGE_BASE_ADDR, (uint32_t *) __buf, PAIRINGS_OFFSET + (MAX_PAIRINGS * sizeof(pairing_data_t)))) { + ERROR("Failed to read the storage sector"); + free(__buf); + return; + } + char *t = buf; + t += sprintf(t, "dump:"); + for (int i = 0; i < (PAIRINGS_OFFSET + (MAX_PAIRINGS * sizeof(pairing_data_t))); i++) { + if (i % 32 == 0) { + INFO("%s", buf); + memset(buf, 0, sizeof(buf)); + t = buf; + } + if (i % 16 == 0 && i % 32 != 0) t += sprintf(t, "- "); + t += sprintf(t, "%02x ", __buf[i]); + } + INFO("%s", buf); + free(__buf); +} +#endif + +int homekit_storage_init(int purge) { STORAGE_DEBUG("EEPROM max: %d B", SPI_FLASH_SEC_SIZE);//4096B STORAGE_DEBUG("Pairing_data size: %d ", (sizeof(pairing_data_t)));//80B STORAGE_DEBUG("MAX pairing count: %d ", MAX_PAIRINGS);//16 - STORAGE_DEBUG("_EEPROM_start: 0x%x (%u)", - HOMEKIT_EEPROM_PHYS_ADDR, HOMEKIT_EEPROM_PHYS_ADDR); - STORAGE_DEBUG("_SPIFFS_start: 0x%x (%u)", - HOMEKIT_SPIFFS_PHYS_ADDR, HOMEKIT_SPIFFS_PHYS_ADDR); + STORAGE_DEBUG("_EEPROM_start: 0x%x (%u)", HOMEKIT_EEPROM_PHYS_ADDR, HOMEKIT_EEPROM_PHYS_ADDR); + STORAGE_DEBUG("_SPIFFS_start: 0x%x (%u)", HOMEKIT_SPIFFS_PHYS_ADDR, HOMEKIT_SPIFFS_PHYS_ADDR); - if (!homekit_storage_magic_valid()) { + int res = 0; // Was valid + if (!homekit_storage_magic_valid() || purge) { INFO("Formatting HomeKit storage at 0x%x", STORAGE_BASE_ADDR); if (!spiflash_erase_sector(STORAGE_BASE_ADDR) || !homekit_storage_set_magic()) { ERROR("Failed to erase HomeKit storage"); return -1; // Fail case } - return 1; // Wasn't valid, is now + res = 1; // Wasn't valid, is now } +#ifdef HOMEKIT_DEBUG pairing_data_t data; int paired = 0; - for (int i=0; i= 'A' && c <= 'F'); } int homekit_storage_load_accessory_id(char *data) { - if (!spiflash_read(ACCESSORY_ID_ADDR, (uint32 *)data, ACCESSORY_ID_SIZE)) { + int size = ACCESSORY_ID_SIZE; + if (size & 3) + size += 4 - (size & 3); + char *d[size]; + if (!spiflash_read(ACCESSORY_ID_ADDR, (uint32_t *) d, size)) { ERROR("Failed to read accessory ID from HomeKit storage"); return -1; } - if (!data[0]) + if (!d[0]) return -2; + memcpy(data, d, ACCESSORY_ID_SIZE); data[ACCESSORY_ID_SIZE] = 0; for (int i=0; imagic, hap_magic, sizeof(hap_magic))) { + for (int i = 0; i < MAX_PAIRINGS; i++) { + pairing_data_t *data = (pairing_data_t *) &storage[PAIRINGS_OFFSET + (i * sizeof(pairing_data_t))]; + if (!memcmp(data->magic, hap_magic, sizeof(hap_magic)) && data->active) { if (i != next_pairing_idx) { - memcpy(&data[PAIRINGS_ADDR + sizeof(pairing_data_t)*next_pairing_idx], - pairing_data, sizeof(*pairing_data)); + memcpy(&storage[PAIRINGS_ADDR + (sizeof(pairing_data_t) * next_pairing_idx)], data, sizeof(*data)); + memset(&storage[PAIRINGS_ADDR + (sizeof(pairing_data_t) * i)], 0, sizeof(*data)); } next_pairing_idx++; } @@ -282,43 +307,47 @@ static int compact_data() { if (next_pairing_idx == MAX_PAIRINGS) { // We are full, no compaction possible, do not waste flash erase cycle - free(data); + free(storage); return 0; } - if (homekit_storage_reset_pairing_data()) { - ERROR("Failed to compact HomeKit storage: error resetting flash"); - free(data); - return -1; + if (!spiflash_erase_sector(STORAGE_BASE_ADDR)) { + ERROR("Failed to erase storage sector"); + free(storage); + return -2; } - if (!spiflash_write(STORAGE_BASE_ADDR, (uint32 *)data, PAIRINGS_OFFSET + sizeof(pairing_data_t)*next_pairing_idx)) { - ERROR("Failed to compact HomeKit storage: error writing compacted data"); - free(data); + + if (!spiflash_write(STORAGE_BASE_ADDR, (uint32_t *) storage, PAIRINGS_OFFSET + (next_pairing_idx * sizeof(pairing_data_t)))) { + ERROR("Failed to compact HomeKit storage: error writing compacted storage"); + free(storage); return -1; } - free(data); + free(storage); return 0; } -int homekit_storage_add_pairing(const char *device_id, const ed25519_key *device_key, byte permissions) { - int next_block_idx = find_empty_block(); - if (next_block_idx == -1) { +static int find_empty_block() { + int index = _find_empty_block(); + if (index == -1) { compact_data(); - next_block_idx = find_empty_block(); + index = _find_empty_block(); } + INFO("empty block %d", index); + return index; +} +int homekit_storage_add_pairing(const char *device_id, const ed25519_key *device_key, byte permissions) { + int next_block_idx = find_empty_block(); if (next_block_idx == -1) { ERROR("Failed to write pairing info to HomeKit storage: max number of pairings"); return -2; } pairing_data_t data; - - bzero(&data, sizeof(data)); + memset(&data, 0xff, sizeof(data)); memcpy(data.magic, hap_magic, sizeof(data.magic)); - data.permissions = permissions; memcpy(data.device_id, device_id, sizeof(data.device_id)); size_t device_public_key_size = sizeof(data.device_public_key); int r = crypto_ed25519_export_public_key( @@ -328,8 +357,9 @@ int homekit_storage_add_pairing(const char *device_id, const ed25519_key *device ERROR("Failed to export device public key (code %d)", r); return -1; } + data.permissions = permissions; - if (!spiflash_write(PAIRINGS_ADDR + sizeof(data)*next_block_idx, (uint32 *)&data, sizeof(data))) { + if (!spiflash_write(PAIRINGS_ADDR + (sizeof(data) * next_block_idx), (uint32_t *) &data, sizeof(data) - 4)) { // last 4 bytes is the status, ff = active, 00 = deleted ERROR("Failed to write pairing info to HomeKit storage"); return -1; } @@ -337,21 +367,20 @@ int homekit_storage_add_pairing(const char *device_id, const ed25519_key *device return 0; } - int homekit_storage_update_pairing(const char *device_id, byte permissions) { pairing_data_t data; - for (int i=0; idevice_key); int r = crypto_ed25519_import_public_key(&pairing->device_key, data.device_public_key, sizeof(data.device_public_key)); if (r) { @@ -440,8 +468,8 @@ int homekit_storage_next_pairing(pairing_iterator_t *it, pairing_t *pairing) { while(it->idx < MAX_PAIRINGS) { int id = it->idx++; - spiflash_read(PAIRINGS_ADDR + sizeof(data)*id, (uint32 *)&data, sizeof(data)); - if (!memcmp(data.magic, hap_magic, sizeof(data.magic))) { + spiflash_read(PAIRINGS_ADDR + (sizeof(data) * id), (uint32_t *) &data, sizeof(data)); + if (!memcmp(data.magic, hap_magic, sizeof(data.magic)) && data.active) { crypto_ed25519_init(&pairing->device_key); int r = crypto_ed25519_import_public_key(&pairing->device_key, data.device_public_key, sizeof(data.device_public_key)); if (r) { @@ -461,6 +489,5 @@ int homekit_storage_next_pairing(pairing_iterator_t *it, pairing_t *pairing) { return -1; } - #undef HOMEKIT_EEPROM_PHYS_ADDR #undef HOMEKIT_SPIFFS_PHYS_ADDR diff --git a/src/storage.h b/src/storage.h index 753768d..a652e39 100644 --- a/src/storage.h +++ b/src/storage.h @@ -15,7 +15,7 @@ bool homekit_storage_set_magic(); int homekit_storage_reset(); int homekit_storage_reset_pairing_data(); -int homekit_storage_init(); +int homekit_storage_init(int purge); void homekit_storage_save_accessory_id(const char *accessory_id); int homekit_storage_load_accessory_id(char *data); From f1c27fade83bb7de32152db05ffc6300b98a1fe7 Mon Sep 17 00:00:00 2001 From: Craig Furter Date: Thu, 20 Jul 2023 00:01:07 +1200 Subject: [PATCH 11/34] Opps, need to return a bool. --- src/storage.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/storage.c b/src/storage.c index 48b3583..2dc5f29 100644 --- a/src/storage.c +++ b/src/storage.c @@ -280,9 +280,9 @@ bool homekit_storage_can_add_pairing() { for (int i = 0; i < MAX_PAIRINGS; i++) { spiflash_read(PAIRINGS_ADDR + (sizeof(data) * i), (uint32_t *) &data, sizeof(data)); if (memcmp(data.magic, hap_magic, sizeof(hap_magic)) || !data.active) - return i; + return true; } - return -1; + return false; } static int compact_data() { From 1339e0aa1094a27ffe82001ffd9b674d128e725c Mon Sep 17 00:00:00 2001 From: Craig Furter Date: Thu, 20 Jul 2023 04:06:16 +1200 Subject: [PATCH 12/34] Last "compact" issue resolved. --- src/storage.c | 51 +++++++++++++++++++++++++++++++++------------------ 1 file changed, 33 insertions(+), 18 deletions(-) diff --git a/src/storage.c b/src/storage.c index 2dc5f29..39d02d3 100644 --- a/src/storage.c +++ b/src/storage.c @@ -98,26 +98,19 @@ bool homekit_storage_set_magic() { #ifdef HOMEKIT_DEBUG static char buf[128]; -static void dump_pairing_data(pairing_data_t *data) { +static void dump_pairing_data(int index, pairing_data_t *data) { if (memcmp(data->magic, hap_magic, sizeof(hap_magic)) || !data->active) return; char *t = buf; - t += sprintf(t, "device_id: %s", data->permissions & pairing_permissions_admin ? "(admin) " : ""); + t += sprintf(t, "device_id (%d): %s", index, data->permissions & pairing_permissions_admin ? "(admin) " : ""); for (int i = 0; i < sizeof(data->device_id); i++) { t += sprintf(t, "%c", data->device_id[i] > 31 && data->device_id[i] < 128 ? data->device_id[i] : '.'); } INFO("%s", buf); } - -void dump_storage() +static void _dump_storage(byte *__buf) { - byte *__buf = malloc(PAIRINGS_OFFSET + (MAX_PAIRINGS * sizeof(pairing_data_t))); - if (!spiflash_read(STORAGE_BASE_ADDR, (uint32_t *) __buf, PAIRINGS_OFFSET + (MAX_PAIRINGS * sizeof(pairing_data_t)))) { - ERROR("Failed to read the storage sector"); - free(__buf); - return; - } char *t = buf; t += sprintf(t, "dump:"); for (int i = 0; i < (PAIRINGS_OFFSET + (MAX_PAIRINGS * sizeof(pairing_data_t))); i++) { @@ -130,6 +123,18 @@ void dump_storage() t += sprintf(t, "%02x ", __buf[i]); } INFO("%s", buf); +} +void dump_storage() +{ + byte *__buf = malloc(PAIRINGS_OFFSET + (MAX_PAIRINGS * sizeof(pairing_data_t))); + + if (!spiflash_read(STORAGE_BASE_ADDR, (uint32_t *) __buf, PAIRINGS_OFFSET + (MAX_PAIRINGS * sizeof(pairing_data_t)))) { + ERROR("Failed to read the storage sector"); + free(__buf); + return; + } + + _dump_storage(__buf); free(__buf); } @@ -157,7 +162,7 @@ int homekit_storage_init(int purge) { int paired = 0; for (int i = 0; i < MAX_PAIRINGS; i++) { spiflash_read(PAIRINGS_ADDR + (sizeof(data) * i), (uint32_t *) &data, sizeof(data)); - dump_pairing_data(&data); + dump_pairing_data(i, &data); if (!memcmp(data.magic, hap_magic, sizeof(hap_magic)) && data.active) { paired++; } @@ -295,11 +300,11 @@ static int compact_data() { int next_pairing_idx = 0; for (int i = 0; i < MAX_PAIRINGS; i++) { - pairing_data_t *data = (pairing_data_t *) &storage[PAIRINGS_OFFSET + (i * sizeof(pairing_data_t))]; - if (!memcmp(data->magic, hap_magic, sizeof(hap_magic)) && data->active) { + pairing_data_t *src = (pairing_data_t *) &storage[PAIRINGS_OFFSET + (i * sizeof(pairing_data_t))]; + if (!memcmp(src->magic, hap_magic, sizeof(hap_magic)) && src->active) { if (i != next_pairing_idx) { - memcpy(&storage[PAIRINGS_ADDR + (sizeof(pairing_data_t) * next_pairing_idx)], data, sizeof(*data)); - memset(&storage[PAIRINGS_ADDR + (sizeof(pairing_data_t) * i)], 0, sizeof(*data)); + pairing_data_t *dest = (pairing_data_t *) &storage[PAIRINGS_OFFSET + (next_pairing_idx * sizeof(pairing_data_t))]; + memcpy(dest, src, sizeof(pairing_data_t)); } next_pairing_idx++; } @@ -316,12 +321,22 @@ static int compact_data() { free(storage); return -2; } - - if (!spiflash_write(STORAGE_BASE_ADDR, (uint32_t *) storage, PAIRINGS_OFFSET + (next_pairing_idx * sizeof(pairing_data_t)))) { - ERROR("Failed to compact HomeKit storage: error writing compacted storage"); + if (!spiflash_write(STORAGE_BASE_ADDR, (uint32_t *) storage, PAIRINGS_OFFSET)) { + ERROR("Failed to compact HomeKit storage: error writing compacted storage header"); free(storage); return -1; } + for (int i = 0; i < next_pairing_idx; i++) { + int offset = PAIRINGS_OFFSET + (i * sizeof(pairing_data_t)); + pairing_data_t *data = (pairing_data_t *) &storage[offset]; + if (!memcmp(data->magic, hap_magic, sizeof(hap_magic)) && data->active) { + if (!spiflash_write(STORAGE_BASE_ADDR + offset, (uint32_t *) &storage[offset], sizeof(pairing_data_t) - 4)) { + ERROR("Failed to compact HomeKit storage: error writing compacted storage"); + free(storage); + return -1; + } + } else break; + } free(storage); From 28cfa6f50b0451bd4bc3e9538324ab4e2106be35 Mon Sep 17 00:00:00 2001 From: David Kerr Date: Sat, 8 Jun 2024 11:18:36 -0400 Subject: [PATCH 13/34] Rename base64_util to base64_utilities to avoid file name conflicts. Courtesy of @JKoss2 --- src/arduino_homekit_server.cpp | 2 +- src/arduino_homekit_server.h | 2 +- src/{base64_util.c => base64_utilities.c} | 2 +- src/{base64_util.h => base64_utilities.h} | 0 4 files changed, 3 insertions(+), 3 deletions(-) rename src/{base64_util.c => base64_utilities.c} (98%) rename src/{base64_util.h => base64_utilities.h} (100%) diff --git a/src/arduino_homekit_server.cpp b/src/arduino_homekit_server.cpp index 117179a..df0516a 100644 --- a/src/arduino_homekit_server.cpp +++ b/src/arduino_homekit_server.cpp @@ -14,7 +14,7 @@ #include //wc_sha512 #include "constants.h" -#include "base64_util.h" +#include "base64_utilities.h" #include "pairing.h" #include "storage.h" #include "query_params.h" diff --git a/src/arduino_homekit_server.h b/src/arduino_homekit_server.h index 3aa1f53..14d3367 100644 --- a/src/arduino_homekit_server.h +++ b/src/arduino_homekit_server.h @@ -11,7 +11,7 @@ extern "C" { #endif #include "constants.h" -#include "base64_util.h" +#include "base64_utilities.h" #include "crypto.h" #include "pairing.h" #include "storage.h" diff --git a/src/base64_util.c b/src/base64_utilities.c similarity index 98% rename from src/base64_util.c rename to src/base64_utilities.c index c7e8a38..d19601e 100644 --- a/src/base64_util.c +++ b/src/base64_utilities.c @@ -1,4 +1,4 @@ -#include "base64_util.h" +#include "base64_utilities.h" static unsigned char base64_chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; diff --git a/src/base64_util.h b/src/base64_utilities.h similarity index 100% rename from src/base64_util.h rename to src/base64_utilities.h From b72a0dce5767d880fae1a9c38cad310feb386275 Mon Sep 17 00:00:00 2001 From: jgstroud Date: Sat, 16 Mar 2024 16:22:51 -0500 Subject: [PATCH 14/34] Remove this non maintained library so we use the upstream wifi lib (cherry picked from commit d4959fd2aa2da01dd5214e6e1aaa94096137ccd9) --- .../src/ESP8266WiFi.cpp | 90 -- .../src/ESP8266WiFi.h | 91 -- .../src/ESP8266WiFiAP.cpp | 383 -------- .../src/ESP8266WiFiAP.h | 58 -- .../src/ESP8266WiFiGeneric.cpp | 817 ------------------ .../src/ESP8266WiFiGeneric.h | 124 --- .../src/ESP8266WiFiMulti.cpp | 269 ------ .../src/ESP8266WiFiMulti.h | 70 -- .../src/ESP8266WiFiSTA.cpp | 784 ----------------- .../src/ESP8266WiFiSTA.h | 114 --- .../src/ESP8266WiFiScan.cpp | 343 -------- .../src/ESP8266WiFiScan.h | 71 -- .../src/ESP8266WiFiType.h | 153 ---- .../src/WiFiClient.cpp | 425 --------- .../ESP8266WiFi_nossl_noleak/src/WiFiClient.h | 135 --- .../src/WiFiServer.cpp | 185 ---- .../ESP8266WiFi_nossl_noleak/src/WiFiServer.h | 75 -- .../ESP8266WiFi_nossl_noleak/src/WiFiUdp.cpp | 281 ------ extras/ESP8266WiFi_nossl_noleak/src/WiFiUdp.h | 113 --- .../src/include/ClientContext.h | 703 --------------- .../src/include/DataSource.h | 154 ---- .../src/include/SSLContext.h | 441 ---------- .../src/include/UdpContext.h | 556 ------------ .../src/include/WiFiState.h | 23 - .../src/include/slist.h | 38 - .../src/include/ssl.h | 583 ------------- .../src/include/wl_definitions.h | 87 -- 27 files changed, 7166 deletions(-) delete mode 100644 extras/ESP8266WiFi_nossl_noleak/src/ESP8266WiFi.cpp delete mode 100644 extras/ESP8266WiFi_nossl_noleak/src/ESP8266WiFi.h delete mode 100644 extras/ESP8266WiFi_nossl_noleak/src/ESP8266WiFiAP.cpp delete mode 100644 extras/ESP8266WiFi_nossl_noleak/src/ESP8266WiFiAP.h delete mode 100644 extras/ESP8266WiFi_nossl_noleak/src/ESP8266WiFiGeneric.cpp delete mode 100644 extras/ESP8266WiFi_nossl_noleak/src/ESP8266WiFiGeneric.h delete mode 100644 extras/ESP8266WiFi_nossl_noleak/src/ESP8266WiFiMulti.cpp delete mode 100644 extras/ESP8266WiFi_nossl_noleak/src/ESP8266WiFiMulti.h delete mode 100644 extras/ESP8266WiFi_nossl_noleak/src/ESP8266WiFiSTA.cpp delete mode 100644 extras/ESP8266WiFi_nossl_noleak/src/ESP8266WiFiSTA.h delete mode 100644 extras/ESP8266WiFi_nossl_noleak/src/ESP8266WiFiScan.cpp delete mode 100644 extras/ESP8266WiFi_nossl_noleak/src/ESP8266WiFiScan.h delete mode 100644 extras/ESP8266WiFi_nossl_noleak/src/ESP8266WiFiType.h delete mode 100644 extras/ESP8266WiFi_nossl_noleak/src/WiFiClient.cpp delete mode 100644 extras/ESP8266WiFi_nossl_noleak/src/WiFiClient.h delete mode 100644 extras/ESP8266WiFi_nossl_noleak/src/WiFiServer.cpp delete mode 100644 extras/ESP8266WiFi_nossl_noleak/src/WiFiServer.h delete mode 100644 extras/ESP8266WiFi_nossl_noleak/src/WiFiUdp.cpp delete mode 100644 extras/ESP8266WiFi_nossl_noleak/src/WiFiUdp.h delete mode 100644 extras/ESP8266WiFi_nossl_noleak/src/include/ClientContext.h delete mode 100644 extras/ESP8266WiFi_nossl_noleak/src/include/DataSource.h delete mode 100644 extras/ESP8266WiFi_nossl_noleak/src/include/SSLContext.h delete mode 100644 extras/ESP8266WiFi_nossl_noleak/src/include/UdpContext.h delete mode 100644 extras/ESP8266WiFi_nossl_noleak/src/include/WiFiState.h delete mode 100644 extras/ESP8266WiFi_nossl_noleak/src/include/slist.h delete mode 100644 extras/ESP8266WiFi_nossl_noleak/src/include/ssl.h delete mode 100644 extras/ESP8266WiFi_nossl_noleak/src/include/wl_definitions.h diff --git a/extras/ESP8266WiFi_nossl_noleak/src/ESP8266WiFi.cpp b/extras/ESP8266WiFi_nossl_noleak/src/ESP8266WiFi.cpp deleted file mode 100644 index 8f63a97..0000000 --- a/extras/ESP8266WiFi_nossl_noleak/src/ESP8266WiFi.cpp +++ /dev/null @@ -1,90 +0,0 @@ -/* - ESP8266WiFi.cpp - WiFi library for esp8266 - - Copyright (c) 2014 Ivan Grokhotkov. All rights reserved. - This file is part of the esp8266 core for Arduino environment. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - Reworked on 28 Dec 2015 by Markus Sattler - - */ - -#include "ESP8266WiFi.h" - -extern "C" { -#include "c_types.h" -#include "ets_sys.h" -#include "os_type.h" -#include "osapi.h" -#include "mem.h" -#include "user_interface.h" -#include "smartconfig.h" -#include "lwip/opt.h" -#include "lwip/err.h" -#include "lwip/dns.h" -} - -#include "debug.h" - -// ----------------------------------------------------------------------------------------------------------------------- -// ---------------------------------------------------------- Debug ------------------------------------------------------ -// ----------------------------------------------------------------------------------------------------------------------- - - -/** - * Output WiFi settings to an object derived from Print interface (like Serial). - * @param p Print interface - */ -void ESP8266WiFiClass::printDiag(Print& p) { - const char* const modes[] = { "NULL", "STA", "AP", "STA+AP" }; - p.print(F("Mode: ")); - p.println(modes[wifi_get_opmode()]); - - const char* const phymodes[] = { "", "B", "G", "N" }; - p.print(F("PHY mode: ")); - p.println(phymodes[(int) wifi_get_phy_mode()]); - - p.print(F("Channel: ")); - p.println(wifi_get_channel()); - - p.print(F("AP id: ")); - p.println(wifi_station_get_current_ap_id()); - - p.print(F("Status: ")); - p.println(wifi_station_get_connect_status()); - - p.print(F("Auto connect: ")); - p.println(wifi_station_get_auto_connect()); - - struct station_config conf; - wifi_station_get_config(&conf); - - char ssid[33]; //ssid can be up to 32chars, => plus null term - memcpy(ssid, conf.ssid, sizeof(conf.ssid)); - ssid[32] = 0; //nullterm in case of 32 char ssid - p.printf_P(PSTR("SSID (%d): %s\n"), strlen(ssid), ssid); - - char passphrase[65]; - memcpy(passphrase, conf.password, sizeof(conf.password)); - passphrase[64] = 0; - p.printf_P(PSTR("Passphrase (%d): %s\n"), strlen(passphrase), passphrase); - - p.print(F("BSSID set: ")); - p.println(conf.bssid_set); - -} - -ESP8266WiFiClass WiFi; diff --git a/extras/ESP8266WiFi_nossl_noleak/src/ESP8266WiFi.h b/extras/ESP8266WiFi_nossl_noleak/src/ESP8266WiFi.h deleted file mode 100644 index 59232e6..0000000 --- a/extras/ESP8266WiFi_nossl_noleak/src/ESP8266WiFi.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - ESP8266WiFi.h - esp8266 Wifi support. - Based on WiFi.h from Arduino WiFi shield library. - Copyright (c) 2011-2014 Arduino. All right reserved. - Modified by Ivan Grokhotkov, December 2014 - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef WiFi_h -#define WiFi_h - -#include - -extern "C" { -#include "include/wl_definitions.h" -} - -#include "IPAddress.h" - -#include "ESP8266WiFiType.h" -#include "ESP8266WiFiSTA.h" -#include "ESP8266WiFiAP.h" -#include "ESP8266WiFiScan.h" -#include "ESP8266WiFiGeneric.h" - -#include "WiFiClient.h" -#include "WiFiServer.h" -//#include "WiFiServerSecure.h" -//#include "WiFiClientSecure.h" -//#include "BearSSLHelpers.h" -//#include "CertStoreBearSSL.h" - -#ifdef DEBUG_ESP_WIFI -#ifdef DEBUG_ESP_PORT -#define DEBUG_WIFI(fmt, ...) DEBUG_ESP_PORT.printf_P( (PGM_P)PSTR(fmt), ##__VA_ARGS__ ) -#endif -#endif - -#ifndef DEBUG_WIFI -#define DEBUG_WIFI(...) do { (void)0; } while (0) -#endif - - -class ESP8266WiFiClass : public ESP8266WiFiGenericClass, public ESP8266WiFiSTAClass, public ESP8266WiFiScanClass, public ESP8266WiFiAPClass { - public: - - // workaround same function name with different signature - using ESP8266WiFiGenericClass::channel; - - using ESP8266WiFiSTAClass::SSID; - using ESP8266WiFiSTAClass::RSSI; - using ESP8266WiFiSTAClass::BSSID; - using ESP8266WiFiSTAClass::BSSIDstr; - - using ESP8266WiFiScanClass::SSID; - using ESP8266WiFiScanClass::encryptionType; - using ESP8266WiFiScanClass::RSSI; - using ESP8266WiFiScanClass::BSSID; - using ESP8266WiFiScanClass::BSSIDstr; - using ESP8266WiFiScanClass::channel; - using ESP8266WiFiScanClass::isHidden; - - // ---------------------------------------------------------------------------------------------- - // ------------------------------------------- Debug -------------------------------------------- - // ---------------------------------------------------------------------------------------------- - - public: - - void printDiag(Print& dest); - - friend class WiFiClient; - friend class WiFiServer; - -}; - -extern ESP8266WiFiClass WiFi; - -#endif diff --git a/extras/ESP8266WiFi_nossl_noleak/src/ESP8266WiFiAP.cpp b/extras/ESP8266WiFi_nossl_noleak/src/ESP8266WiFiAP.cpp deleted file mode 100644 index e51f5d4..0000000 --- a/extras/ESP8266WiFi_nossl_noleak/src/ESP8266WiFiAP.cpp +++ /dev/null @@ -1,383 +0,0 @@ -/* - ESP8266WiFiSTA.cpp - WiFi library for esp8266 - - Copyright (c) 2014 Ivan Grokhotkov. All rights reserved. - This file is part of the esp8266 core for Arduino environment. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - Reworked on 28 Dec 2015 by Markus Sattler - - */ - -#include "ESP8266WiFi.h" -#include "ESP8266WiFiGeneric.h" -#include "ESP8266WiFiAP.h" - -extern "C" { -#include "c_types.h" -#include "ets_sys.h" -#include "os_type.h" -#include "osapi.h" -#include "mem.h" -#include "user_interface.h" -} - -#include "debug.h" - - - -// ----------------------------------------------------------------------------------------------------------------------- -// ---------------------------------------------------- Private functions ------------------------------------------------ -// ----------------------------------------------------------------------------------------------------------------------- - -static bool softap_config_equal(const softap_config& lhs, const softap_config& rhs); - - - -/** - * compare two AP configurations - * @param lhs softap_config - * @param rhs softap_config - * @return equal - */ -static bool softap_config_equal(const softap_config& lhs, const softap_config& rhs) { - if(strcmp(reinterpret_cast(lhs.ssid), reinterpret_cast(rhs.ssid)) != 0) { - return false; - } - if(strcmp(reinterpret_cast(lhs.password), reinterpret_cast(rhs.password)) != 0) { - return false; - } - if(lhs.channel != rhs.channel) { - return false; - } - if(lhs.ssid_hidden != rhs.ssid_hidden) { - return false; - } - if(lhs.max_connection != rhs.max_connection) { - return false; - } - if(lhs.beacon_interval != rhs.beacon_interval) { - return false; - } - if(lhs.authmode != rhs.authmode) { - return false; - } - return true; -} - -// ----------------------------------------------------------------------------------------------------------------------- -// ----------------------------------------------------- AP function ----------------------------------------------------- -// ----------------------------------------------------------------------------------------------------------------------- - - -/** - * Set up an access point - * @param ssid Pointer to the SSID (max 31 char). - * @param passphrase For WPA2 min 8 char, for open use NULL (max 63 char). - * @param channel WiFi channel number, 1 - 13. - * @param ssid_hidden Network cloaking (0 = broadcast SSID, 1 = hide SSID) - * @param max_connection Max simultaneous connected clients, 0 - 8. https://bbs.espressif.com/viewtopic.php?f=46&t=481&p=1832&hilit=max_connection#p1832 - */ -bool ESP8266WiFiAPClass::softAP(const char* ssid, const char* passphrase, int channel, int ssid_hidden, int max_connection) { - - if(!WiFi.enableAP(true)) { - // enable AP failed - DEBUG_WIFI("[AP] enableAP failed!\n"); - return false; - } - - if(!ssid || strlen(ssid) == 0 || strlen(ssid) > 31) { - // fail SSID too long or missing! - DEBUG_WIFI("[AP] SSID too long or missing!\n"); - return false; - } - - if(passphrase && strlen(passphrase) > 0 && (strlen(passphrase) > 63 || strlen(passphrase) < 8)) { - // fail passphrase to long or short! - DEBUG_WIFI("[AP] fail passphrase too long or short!\n"); - return false; - } - - bool ret = true; - - struct softap_config conf; - strcpy(reinterpret_cast(conf.ssid), ssid); - conf.channel = channel; - conf.ssid_len = strlen(ssid); - conf.ssid_hidden = ssid_hidden; - conf.max_connection = max_connection; - conf.beacon_interval = 100; - - if(!passphrase || strlen(passphrase) == 0) { - conf.authmode = AUTH_OPEN; - *conf.password = 0; - } else { - conf.authmode = AUTH_WPA2_PSK; - strcpy(reinterpret_cast(conf.password), passphrase); - } - - struct softap_config conf_compare; - if(WiFi._persistent){ - wifi_softap_get_config_default(&conf_compare); - } - else { - wifi_softap_get_config(&conf_compare); - } - - if(!softap_config_equal(conf, conf_compare)) { - - ETS_UART_INTR_DISABLE(); - if(WiFi._persistent) { - ret = wifi_softap_set_config(&conf); - } else { - ret = wifi_softap_set_config_current(&conf); - } - ETS_UART_INTR_ENABLE(); - - if(!ret) { - DEBUG_WIFI("[AP] set_config failed!\n"); - return false; - } - - } else { - DEBUG_WIFI("[AP] softap config unchanged\n"); - } - - if(wifi_softap_dhcps_status() != DHCP_STARTED) { - DEBUG_WIFI("[AP] DHCP not started, starting...\n"); - if(!wifi_softap_dhcps_start()) { - DEBUG_WIFI("[AP] wifi_softap_dhcps_start failed!\n"); - ret = false; - } - } - - // check IP config - struct ip_info ip; - if(wifi_get_ip_info(SOFTAP_IF, &ip)) { - if(ip.ip.addr == 0x00000000) { - // Invalid config - DEBUG_WIFI("[AP] IP config Invalid resetting...\n"); - //192.168.244.1 , 192.168.244.1 , 255.255.255.0 - ret = softAPConfig(0x01F4A8C0, 0x01F4A8C0, 0x00FFFFFF); - if(!ret) { - DEBUG_WIFI("[AP] softAPConfig failed!\n"); - ret = false; - } - } - } else { - DEBUG_WIFI("[AP] wifi_get_ip_info failed!\n"); - ret = false; - } - - return ret; -} - -bool ESP8266WiFiAPClass::softAP(const String& ssid, const String& passphrase, int channel, int ssid_hidden, int max_connection) { - return softAP(ssid.c_str(), passphrase.c_str(), channel, ssid_hidden, max_connection); -} - -/** - * Configure access point - * @param local_ip access point IP - * @param gateway gateway IP (0.0.0.0 to disable) - * @param subnet subnet mask - */ -bool ESP8266WiFiAPClass::softAPConfig(IPAddress local_ip, IPAddress gateway, IPAddress subnet) { - DEBUG_WIFI("[APConfig] local_ip: %s gateway: %s subnet: %s\n", local_ip.toString().c_str(), gateway.toString().c_str(), subnet.toString().c_str()); - if(!WiFi.enableAP(true)) { - // enable AP failed - DEBUG_WIFI("[APConfig] enableAP failed!\n"); - return false; - } - bool ret = true; - - if ( !local_ip.isV4() - || !subnet.isV4() -#if LWIP_IPV6 - // uninitialized gateway is valid - || gateway.isV6() -#endif - ) { - return false; - } - struct ip_info info; - info.ip.addr = local_ip.v4(); - info.gw.addr = gateway.v4(); - info.netmask.addr = subnet.v4(); - - if(!wifi_softap_dhcps_stop()) { - DEBUG_WIFI("[APConfig] wifi_softap_dhcps_stop failed!\n"); - } - - if(!wifi_set_ip_info(SOFTAP_IF, &info)) { - DEBUG_WIFI("[APConfig] wifi_set_ip_info failed!\n"); - ret = false; - } - - struct dhcps_lease dhcp_lease; - IPAddress ip = local_ip; - ip[3] += 99; - dhcp_lease.start_ip.addr = ip.v4(); - DEBUG_WIFI("[APConfig] DHCP IP start: %s\n", ip.toString().c_str()); - - ip[3] += 100; - dhcp_lease.end_ip.addr = ip.v4(); - DEBUG_WIFI("[APConfig] DHCP IP end: %s\n", ip.toString().c_str()); - - if(!wifi_softap_set_dhcps_lease(&dhcp_lease)) { - DEBUG_WIFI("[APConfig] wifi_set_ip_info failed!\n"); - ret = false; - } - - // set lease time to 720min --> 12h - if(!wifi_softap_set_dhcps_lease_time(720)) { - DEBUG_WIFI("[APConfig] wifi_softap_set_dhcps_lease_time failed!\n"); - ret = false; - } - - uint8 mode = info.gw.addr ? 1 : 0; - if(!wifi_softap_set_dhcps_offer_option(OFFER_ROUTER, &mode)) { - DEBUG_WIFI("[APConfig] wifi_softap_set_dhcps_offer_option failed!\n"); - ret = false; - } - - if(!wifi_softap_dhcps_start()) { - DEBUG_WIFI("[APConfig] wifi_softap_dhcps_start failed!\n"); - ret = false; - } - - // check config - if(wifi_get_ip_info(SOFTAP_IF, &info)) { - if(info.ip.addr == 0x00000000) { - DEBUG_WIFI("[APConfig] IP config Invalid?!\n"); - ret = false; - } else if(local_ip.v4() != info.ip.addr) { - ip = info.ip.addr; - DEBUG_WIFI("[APConfig] IP config not set correct?! new IP: %s\n", ip.toString().c_str()); - ret = false; - } - } else { - DEBUG_WIFI("[APConfig] wifi_get_ip_info failed!\n"); - ret = false; - } - - return ret; -} - - - -/** - * Disconnect from the network (close AP) - * @param wifioff disable mode? - * @return one value of wl_status_t enum - */ -bool ESP8266WiFiAPClass::softAPdisconnect(bool wifioff) { - bool ret; - struct softap_config conf; - *conf.ssid = 0; - *conf.password = 0; - conf.authmode = AUTH_OPEN; - ETS_UART_INTR_DISABLE(); - if(WiFi._persistent) { - ret = wifi_softap_set_config(&conf); - } else { - ret = wifi_softap_set_config_current(&conf); - } - ETS_UART_INTR_ENABLE(); - - if(!ret) { - DEBUG_WIFI("[APdisconnect] set_config failed!\n"); - } - - if(ret && wifioff) { - ret = WiFi.enableAP(false); - } - - return ret; -} - - -/** - * Get the count of the Station / client that are connected to the softAP interface - * @return Stations count - */ -uint8_t ESP8266WiFiAPClass::softAPgetStationNum() { - return wifi_softap_get_station_num(); -} - -/** - * Get the softAP interface IP address. - * @return IPAddress softAP IP - */ -IPAddress ESP8266WiFiAPClass::softAPIP() { - struct ip_info ip; - wifi_get_ip_info(SOFTAP_IF, &ip); - return IPAddress(ip.ip.addr); -} - - -/** - * Get the softAP interface MAC address. - * @param mac pointer to uint8_t array with length WL_MAC_ADDR_LENGTH - * @return pointer to uint8_t* - */ -uint8_t* ESP8266WiFiAPClass::softAPmacAddress(uint8_t* mac) { - wifi_get_macaddr(SOFTAP_IF, mac); - return mac; -} - -/** - * Get the softAP interface MAC address. - * @return String mac - */ -String ESP8266WiFiAPClass::softAPmacAddress(void) { - uint8_t mac[6]; - char macStr[18] = { 0 }; - wifi_get_macaddr(SOFTAP_IF, mac); - - sprintf(macStr, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); - return String(macStr); -} - -/** - * Get the configured(Not-In-Flash) softAP SSID name. - * @return String SSID. - */ -String ESP8266WiFiAPClass::softAPSSID() const { - struct softap_config config; - wifi_softap_get_config(&config); - char* name = reinterpret_cast(config.ssid); - char ssid[sizeof(config.ssid) + 1]; - memcpy(ssid, name, sizeof(config.ssid)); - ssid[sizeof(config.ssid)] = '\0'; - - return String(ssid); -} - -/** - * Get the configured(Not-In-Flash) softAP PSK or PASSWORD. - * @return String psk. - */ -String ESP8266WiFiAPClass::softAPPSK() const { - struct softap_config config; - wifi_softap_get_config(&config); - char* pass = reinterpret_cast(config.password); - char psk[sizeof(config.password) + 1]; - memcpy(psk, pass, sizeof(config.password)); - psk[sizeof(config.password)] = '\0'; - - return String(psk); -} diff --git a/extras/ESP8266WiFi_nossl_noleak/src/ESP8266WiFiAP.h b/extras/ESP8266WiFi_nossl_noleak/src/ESP8266WiFiAP.h deleted file mode 100644 index 74e8850..0000000 --- a/extras/ESP8266WiFi_nossl_noleak/src/ESP8266WiFiAP.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - ESP8266WiFiAP.h - esp8266 Wifi support. - Based on WiFi.h from Arduino WiFi shield library. - Copyright (c) 2011-2014 Arduino. All right reserved. - Modified by Ivan Grokhotkov, December 2014 - Reworked by Markus Sattler, December 2015 - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef ESP8266WIFIAP_H_ -#define ESP8266WIFIAP_H_ - - -#include "ESP8266WiFiType.h" -#include "ESP8266WiFiGeneric.h" - - -class ESP8266WiFiAPClass { - - // ---------------------------------------------------------------------------------------------- - // ----------------------------------------- AP function ---------------------------------------- - // ---------------------------------------------------------------------------------------------- - - public: - - bool softAP(const char* ssid, const char* passphrase = NULL, int channel = 1, int ssid_hidden = 0, int max_connection = 4); - bool softAP(const String& ssid,const String& passphrase = emptyString,int channel = 1,int ssid_hidden = 0,int max_connection = 4); - bool softAPConfig(IPAddress local_ip, IPAddress gateway, IPAddress subnet); - bool softAPdisconnect(bool wifioff = false); - - uint8_t softAPgetStationNum(); - - IPAddress softAPIP(); - - uint8_t* softAPmacAddress(uint8_t* mac); - String softAPmacAddress(void); - - String softAPSSID() const; - String softAPPSK() const; - - protected: - -}; - -#endif /* ESP8266WIFIAP_H_*/ diff --git a/extras/ESP8266WiFi_nossl_noleak/src/ESP8266WiFiGeneric.cpp b/extras/ESP8266WiFi_nossl_noleak/src/ESP8266WiFiGeneric.cpp deleted file mode 100644 index 4b2eb54..0000000 --- a/extras/ESP8266WiFi_nossl_noleak/src/ESP8266WiFiGeneric.cpp +++ /dev/null @@ -1,817 +0,0 @@ -/* - ESP8266WiFiGeneric.cpp - WiFi library for esp8266 - - Copyright (c) 2014 Ivan Grokhotkov. All rights reserved. - This file is part of the esp8266 core for Arduino environment. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - Reworked on 28 Dec 2015 by Markus Sattler - - */ - -#include -#include -#include -#include -#include "ESP8266WiFi.h" -#include "ESP8266WiFiGeneric.h" - -extern "C" { -#include "c_types.h" -#include "ets_sys.h" -#include "os_type.h" -#include "osapi.h" -#include "mem.h" -#include "user_interface.h" - -#include "lwip/opt.h" -#include "lwip/err.h" -#include "lwip/dns.h" -#include "lwip/dhcp.h" -#include "lwip/init.h" // LWIP_VERSION_ -#if LWIP_VERSION_MAJOR == 1 -#include "lwip/sntp.h" -#else -#include "lwip/apps/sntp.h" -#endif -} - -#include "WiFiClient.h" -#include "WiFiUdp.h" -#include "debug.h" -#include "include/WiFiState.h" - -extern "C" void esp_schedule(); -extern "C" void esp_yield(); - - -// ----------------------------------------------------------------------------------------------------------------------- -// ------------------------------------------------- Generic WiFi function ----------------------------------------------- -// ----------------------------------------------------------------------------------------------------------------------- - -struct WiFiEventHandlerOpaque -{ - WiFiEventHandlerOpaque(WiFiEvent_t event, std::function handler) - : mEvent(event), mHandler(handler) - { - } - - void operator()(System_Event_t* e) - { - if (static_cast(e->event) == mEvent || mEvent == WIFI_EVENT_ANY) { - mHandler(e); - } - } - - bool canExpire() - { - return mCanExpire; - } - - WiFiEvent_t mEvent; - std::function mHandler; - bool mCanExpire = true; /* stopgap solution to handle deprecated void onEvent(cb, evt) case */ -}; - -static std::list sCbEventList; - -bool ESP8266WiFiGenericClass::_persistent = true; -WiFiMode_t ESP8266WiFiGenericClass::_forceSleepLastMode = WIFI_OFF; - -ESP8266WiFiGenericClass::ESP8266WiFiGenericClass() -{ - wifi_set_event_handler_cb((wifi_event_handler_cb_t) &ESP8266WiFiGenericClass::_eventCallback); -} - -void ESP8266WiFiGenericClass::onEvent(WiFiEventCb f, WiFiEvent_t event) -{ - WiFiEventHandler handler = std::make_shared(event, [f](System_Event_t* e) { - (*f)(static_cast(e->event)); - }); - handler->mCanExpire = false; - sCbEventList.push_back(handler); -} - -WiFiEventHandler ESP8266WiFiGenericClass::onStationModeConnected(std::function f) -{ - WiFiEventHandler handler = std::make_shared(WIFI_EVENT_STAMODE_CONNECTED, [f](System_Event_t* e) { - auto& src = e->event_info.connected; - WiFiEventStationModeConnected dst; - dst.ssid = String(reinterpret_cast(src.ssid)); - memcpy(dst.bssid, src.bssid, 6); - dst.channel = src.channel; - f(dst); - }); - sCbEventList.push_back(handler); - return handler; -} - -WiFiEventHandler ESP8266WiFiGenericClass::onStationModeDisconnected(std::function f) -{ - WiFiEventHandler handler = std::make_shared(WIFI_EVENT_STAMODE_DISCONNECTED, [f](System_Event_t* e){ - auto& src = e->event_info.disconnected; - WiFiEventStationModeDisconnected dst; - dst.ssid = String(reinterpret_cast(src.ssid)); - memcpy(dst.bssid, src.bssid, 6); - dst.reason = static_cast(src.reason); - f(dst); - }); - sCbEventList.push_back(handler); - return handler; -} - -WiFiEventHandler ESP8266WiFiGenericClass::onStationModeAuthModeChanged(std::function f) -{ - WiFiEventHandler handler = std::make_shared(WIFI_EVENT_STAMODE_AUTHMODE_CHANGE, [f](System_Event_t* e){ - auto& src = e->event_info.auth_change; - WiFiEventStationModeAuthModeChanged dst; - dst.oldMode = src.old_mode; - dst.newMode = src.new_mode; - f(dst); - }); - sCbEventList.push_back(handler); - return handler; -} - -WiFiEventHandler ESP8266WiFiGenericClass::onStationModeGotIP(std::function f) -{ - WiFiEventHandler handler = std::make_shared(WIFI_EVENT_STAMODE_GOT_IP, [f](System_Event_t* e){ - auto& src = e->event_info.got_ip; - WiFiEventStationModeGotIP dst; - dst.ip = src.ip.addr; - dst.mask = src.mask.addr; - dst.gw = src.gw.addr; - f(dst); - }); - sCbEventList.push_back(handler); - return handler; -} - -WiFiEventHandler ESP8266WiFiGenericClass::onStationModeDHCPTimeout(std::function f) -{ - WiFiEventHandler handler = std::make_shared(WIFI_EVENT_STAMODE_DHCP_TIMEOUT, [f](System_Event_t* e){ - (void) e; - f(); - }); - sCbEventList.push_back(handler); - return handler; -} - -WiFiEventHandler ESP8266WiFiGenericClass::onSoftAPModeStationConnected(std::function f) -{ - WiFiEventHandler handler = std::make_shared(WIFI_EVENT_SOFTAPMODE_STACONNECTED, [f](System_Event_t* e){ - auto& src = e->event_info.sta_connected; - WiFiEventSoftAPModeStationConnected dst; - memcpy(dst.mac, src.mac, 6); - dst.aid = src.aid; - f(dst); - }); - sCbEventList.push_back(handler); - return handler; -} - -WiFiEventHandler ESP8266WiFiGenericClass::onSoftAPModeStationDisconnected(std::function f) -{ - WiFiEventHandler handler = std::make_shared(WIFI_EVENT_SOFTAPMODE_STADISCONNECTED, [f](System_Event_t* e){ - auto& src = e->event_info.sta_disconnected; - WiFiEventSoftAPModeStationDisconnected dst; - memcpy(dst.mac, src.mac, 6); - dst.aid = src.aid; - f(dst); - }); - sCbEventList.push_back(handler); - return handler; -} - -WiFiEventHandler ESP8266WiFiGenericClass::onSoftAPModeProbeRequestReceived(std::function f) -{ - WiFiEventHandler handler = std::make_shared(WIFI_EVENT_SOFTAPMODE_PROBEREQRECVED, [f](System_Event_t* e){ - auto& src = e->event_info.ap_probereqrecved; - WiFiEventSoftAPModeProbeRequestReceived dst; - memcpy(dst.mac, src.mac, 6); - dst.rssi = src.rssi; - f(dst); - }); - sCbEventList.push_back(handler); - return handler; -} - -WiFiEventHandler ESP8266WiFiGenericClass::onWiFiModeChange(std::function f) -{ - WiFiEventHandler handler = std::make_shared(WIFI_EVENT_MODE_CHANGE, [f](System_Event_t* e){ - WiFiEventModeChange& dst = *reinterpret_cast(&e->event_info); - f(dst); - }); - sCbEventList.push_back(handler); - return handler; -} - -/** - * callback for WiFi events - * @param arg - */ -void ESP8266WiFiGenericClass::_eventCallback(void* arg) -{ - System_Event_t* event = reinterpret_cast(arg); - DEBUG_WIFI("wifi evt: %d\n", event->event); - - if(event->event == EVENT_STAMODE_DISCONNECTED) { - DEBUG_WIFI("STA disconnect: %d\n", event->event_info.disconnected.reason); - WiFiClient::stopAll(); - } - - for(auto it = std::begin(sCbEventList); it != std::end(sCbEventList); ) { - WiFiEventHandler &handler = *it; - if (handler->canExpire() && handler.unique()) { - it = sCbEventList.erase(it); - } - else { - (*handler)(event); - ++it; - } - } -} - -/** - * Return the current channel associated with the network - * @return channel (1-13) - */ -int32_t ESP8266WiFiGenericClass::channel(void) { - return wifi_get_channel(); -} - -/** - * set Sleep mode - * @param type sleep_type_t - * @return bool - */ -bool ESP8266WiFiGenericClass::setSleepMode(WiFiSleepType_t type, uint8_t listenInterval) { - - /** - * datasheet: - * - wifi_set_sleep_level(): - Set sleep level of modem sleep and light sleep - This configuration should be called before calling wifi_set_sleep_type - Modem-sleep and light sleep mode have minimum and maximum sleep levels. - - In minimum sleep level, station wakes up at every DTIM to receive - beacon. Broadcast data will not be lost because it is transmitted after - DTIM. However, it can not save much more power if DTIM period is short, - as specified in AP. - - In maximum sleep level, station wakes up at every listen interval to - receive beacon. Broadcast data may be lost because station may be in sleep - state at DTIM time. If listen interval is longer, more power will be saved, but - it’s very likely to lose more broadcast data. - - Default setting is minimum sleep level. - Further reading: https://routerguide.net/dtim-interval-period-best-setting/ - - wifi_set_listen_interval(): - Set listen interval of maximum sleep level for modem sleep and light sleep - It only works when sleep level is set as MAX_SLEEP_T - forum: https://github.com/espressif/ESP8266_NONOS_SDK/issues/165#issuecomment-416121920 - default value seems to be 3 (as recommended by https://routerguide.net/dtim-interval-period-best-setting/) - - call order: - wifi_set_sleep_level(MAX_SLEEP_T) (SDK3) - wifi_set_listen_interval (SDK3) - wifi_set_sleep_type (all SDKs) - - */ - -#ifdef NONOSDK3V0 - -#ifdef DEBUG_ESP_WIFI - if (listenInterval && type == WIFI_NONE_SLEEP) - DEBUG_WIFI_GENERIC("listenInterval not usable with WIFI_NONE_SLEEP\n"); -#endif - - if (type == WIFI_LIGHT_SLEEP || type == WIFI_MODEM_SLEEP) { - if (listenInterval) { - if (!wifi_set_sleep_level(MAX_SLEEP_T)) { - DEBUG_WIFI_GENERIC("wifi_set_sleep_level(MAX_SLEEP_T): error\n"); - return false; - } - if (listenInterval > 10) { - DEBUG_WIFI_GENERIC("listenInterval must be in [1..10]\n"); -#ifndef DEBUG_ESP_WIFI - // stay within datasheet range when not in debug mode - listenInterval = 10; -#endif - } - if (!wifi_set_listen_interval(listenInterval)) { - DEBUG_WIFI_GENERIC("wifi_set_listen_interval(%d): error\n", listenInterval); - return false; - } - } else { - if (!wifi_set_sleep_level(MIN_SLEEP_T)) { - DEBUG_WIFI_GENERIC("wifi_set_sleep_level(MIN_SLEEP_T): error\n"); - return false; - } - } - } -#else // !defined(NONOSDK3V0) - (void)listenInterval; -#endif // !defined(NONOSDK3V0) - - bool ret = wifi_set_sleep_type((sleep_type_t) type); - if (!ret) { - DEBUG_WIFI_GENERIC("wifi_set_sleep_type(%d): error\n", (int)type); - } - return ret; -} - -/** - * get Sleep mode - * @return sleep_type_t - */ -WiFiSleepType_t ESP8266WiFiGenericClass::getSleepMode() { - return (WiFiSleepType_t) wifi_get_sleep_type(); -} - -/** - * set phy Mode - * @param mode phy_mode_t - * @return bool - */ -bool ESP8266WiFiGenericClass::setPhyMode(WiFiPhyMode_t mode) { - return wifi_set_phy_mode((phy_mode_t) mode); -} - -/** - * get phy Mode - * @return phy_mode_t - */ -WiFiPhyMode_t ESP8266WiFiGenericClass::getPhyMode() { - return (WiFiPhyMode_t) wifi_get_phy_mode(); -} - -/** - * set the output power of WiFi - * @param dBm max: +20.5dBm min: 0dBm - */ -void ESP8266WiFiGenericClass::setOutputPower(float dBm) { - - if(dBm > 20.5) { - dBm = 20.5; - } else if(dBm < 0) { - dBm = 0; - } - - uint8_t val = (dBm*4.0f); - system_phy_set_max_tpw(val); -} - - -/** - * store WiFi config in SDK flash area - * @param persistent - */ -void ESP8266WiFiGenericClass::persistent(bool persistent) { - _persistent = persistent; -} - -/** - * gets the persistent state - * @return bool - */ -bool ESP8266WiFiGenericClass::getPersistent(){ - return _persistent; -} - -/** - * set new mode - * @param m WiFiMode_t - */ -bool ESP8266WiFiGenericClass::mode(WiFiMode_t m, WiFiState* state) { - if (m == WIFI_SHUTDOWN) { - return shutdown(0, state); - } - else if (m == WIFI_RESUME) { - return resumeFromShutdown(state); - } - else if (m & ~(WIFI_STA | WIFI_AP)) - // any other bits than legacy disallowed - return false; - - // m is now WIFI_STA, WIFI_AP or WIFI_AP_STA - if (state) - { - DEBUG_WIFI("core: state is useless without SHUTDOWN or RESUME\n"); - } - - if (wifi_fpm_get_sleep_type() != NONE_SLEEP_T) { - // wifi may have been put asleep by ESP8266WiFiGenericClass::preinitWiFiOff - wifi_fpm_do_wakeup(); - wifi_fpm_close(); - } - - if(_persistent){ - if(wifi_get_opmode() == (uint8) m && wifi_get_opmode_default() == (uint8) m){ - return true; - } - } else if(wifi_get_opmode() == (uint8) m){ - return true; - } - - bool ret = false; - ETS_UART_INTR_DISABLE(); - if(_persistent) { - ret = wifi_set_opmode(m); - } else { - ret = wifi_set_opmode_current(m); - } - ETS_UART_INTR_ENABLE(); - - if(!ret) - return false; //calling wifi_set_opmode failed - - //Wait for mode change, which is asynchronous. - //Only wait if in CONT context. If this were called from SYS, it's up to the user to serialize - //tasks to wait correctly. - constexpr unsigned int timeoutValue = 1000; //1 second - if(can_yield()) { - using oneShot = esp8266::polledTimeout::oneShotFastMs; - oneShot timeout(timeoutValue); - while(wifi_get_opmode() != (uint8) m && !timeout) - delay(5); - - //if at this point mode still hasn't been reached, give up - if(wifi_get_opmode() != (uint8) m) { - return false; //timeout - } - } - - return ret; -} - -/** - * get WiFi mode - * @return WiFiMode - */ -WiFiMode_t ESP8266WiFiGenericClass::getMode() { - return (WiFiMode_t) wifi_get_opmode(); -} - -/** - * control STA mode - * @param enable bool - * @return ok - */ -bool ESP8266WiFiGenericClass::enableSTA(bool enable) { - - WiFiMode_t currentMode = getMode(); - bool isEnabled = ((currentMode & WIFI_STA) != 0); - - if (isEnabled == enable) - return true; - - if (enable) - return mode((WiFiMode_t)(currentMode | WIFI_STA)); - - return mode((WiFiMode_t)(currentMode & (~WIFI_STA))); -} - -/** - * control AP mode - * @param enable bool - * @return ok - */ -bool ESP8266WiFiGenericClass::enableAP(bool enable){ - - WiFiMode_t currentMode = getMode(); - bool isEnabled = ((currentMode & WIFI_AP) != 0); - - if(isEnabled != enable) { - if(enable) { - return mode((WiFiMode_t)(currentMode | WIFI_AP)); - } else { - return mode((WiFiMode_t)(currentMode & (~WIFI_AP))); - } - } else { - return true; - } -} - - -/** - * Disable WiFi for x us when value is not 0 - * @param sleep_time_in_us - * @return ok - */ -bool ESP8266WiFiGenericClass::forceSleepBegin(uint32 sleepUs) { - _forceSleepLastMode = getMode(); - if(!mode(WIFI_OFF)) { - DEBUG_WIFI("core: error with mode(WIFI_OFF)\n"); - return false; - } - - if(sleepUs == 0 || sleepUs > 0xFFFFFFF) { - sleepUs = 0xFFFFFFF; - } - - wifi_fpm_set_sleep_type(MODEM_SLEEP_T); - delay(0); - wifi_fpm_open(); - delay(0); - auto ret = wifi_fpm_do_sleep(sleepUs); - if (ret != 0) - { - DEBUG_WIFI("core: error %d with wifi_fpm_do_sleep: (-1=sleep status error, -2=force sleep not enabled)\n", ret); - return false; - } - // fpm_is_open() is always 1 here, with or without delay - // wifi_fpm_set_wakeup_cb(cb): callback is never called - // no power reduction without this delay - delay(10); - return true; -} - -/** - * wake up WiFi Modem - * @return ok - */ -bool ESP8266WiFiGenericClass::forceSleepWake() { - if (wifi_fpm_get_sleep_type() != NONE_SLEEP_T) { - wifi_fpm_do_wakeup(); - wifi_fpm_close(); - } - - // restore last mode - if(mode(_forceSleepLastMode)) { - if((_forceSleepLastMode & WIFI_STA) != 0){ - wifi_station_connect(); - } - return true; - } - return false; -} - -/** - * Get listen interval of maximum sleep level for modem sleep and light sleep. - * @return interval - */ -uint8_t ESP8266WiFiGenericClass::getListenInterval () { -#ifndef NONOSDK3V0 - return 0; -#else - return wifi_get_listen_interval(); -#endif -} - -/** - * Get sleep level of modem sleep and light sleep - * @return true if max level - */ -bool ESP8266WiFiGenericClass::isSleepLevelMax () { -#ifndef NONOSDK3V0 - return false; -#else - return wifi_get_sleep_level() == MAX_SLEEP_T; -#endif -} - - -// ----------------------------------------------------------------------------------------------------------------------- -// ------------------------------------------------ Generic Network function --------------------------------------------- -// ----------------------------------------------------------------------------------------------------------------------- - -void wifi_dns_found_callback(const char *name, CONST ip_addr_t *ipaddr, void *callback_arg); - -static bool _dns_lookup_pending = false; - -/** - * Resolve the given hostname to an IP address. - * @param aHostname Name to be resolved - * @param aResult IPAddress structure to store the returned IP address - * @return 1 if aIPAddrString was successfully converted to an IP address, - * else 0 - */ -int ESP8266WiFiGenericClass::hostByName(const char* aHostname, IPAddress& aResult) -{ - return hostByName(aHostname, aResult, 10000); -} - - -int ESP8266WiFiGenericClass::hostByName(const char* aHostname, IPAddress& aResult, uint32_t timeout_ms) -{ - ip_addr_t addr; - aResult = static_cast(0); - - if(aResult.fromString(aHostname)) { - // Host name is a IP address use it! - DEBUG_WIFI_GENERIC("[hostByName] Host: %s is a IP!\n", aHostname); - return 1; - } - - DEBUG_WIFI_GENERIC("[hostByName] request IP for: %s\n", aHostname); - err_t err = dns_gethostbyname(aHostname, &addr, &wifi_dns_found_callback, &aResult); - if(err == ERR_OK) { - aResult = IPAddress(&addr); - } else if(err == ERR_INPROGRESS) { - _dns_lookup_pending = true; - delay(timeout_ms); - // will resume on timeout or when wifi_dns_found_callback fires - _dns_lookup_pending = false; - // will return here when dns_found_callback fires - if(aResult.isSet()) { - err = ERR_OK; - } - } - - if(err != 0) { - DEBUG_WIFI_GENERIC("[hostByName] Host: %s lookup error: %d!\n", aHostname, (int)err); - } else { - DEBUG_WIFI_GENERIC("[hostByName] Host: %s IP: %s\n", aHostname, aResult.toString().c_str()); - } - - return (err == ERR_OK) ? 1 : 0; -} - -/** - * DNS callback - * @param name - * @param ipaddr - * @param callback_arg - */ -void wifi_dns_found_callback(const char *name, CONST ip_addr_t *ipaddr, void *callback_arg) -{ - (void) name; - if (!_dns_lookup_pending) { - return; - } - if(ipaddr) { - (*reinterpret_cast(callback_arg)) = IPAddress(ipaddr); - } - esp_schedule(); // break delay in hostByName -} - -uint32_t ESP8266WiFiGenericClass::shutdownCRC (const WiFiState* state) -{ - return state? crc32(&state->state, sizeof(state->state)): 0; -} - -bool ESP8266WiFiGenericClass::shutdownValidCRC (const WiFiState* state) -{ - return state && (crc32(&state->state, sizeof(state->state)) == state->crc); -} - -bool ESP8266WiFiGenericClass::shutdown (uint32 sleepUs, WiFiState* state) -{ - bool persistent = _persistent; - WiFiMode_t before_off_mode = getMode(); - - if ((before_off_mode & WIFI_STA) && state) - { - bool ret = wifi_get_ip_info(STATION_IF, &state->state.ip); - if (!ret) - { - DEBUG_WIFI("core: error with wifi_get_ip_info(STATION_IF)\n"); - return false; - } - memset(state->state.fwconfig.bssid, 0xff, 6); - ret = wifi_station_get_config(&state->state.fwconfig); - if (!ret) - { - DEBUG_WIFI("core: error with wifi_station_get_config\n"); - return false; - } - state->state.channel = wifi_get_channel(); - } - - // disable persistence in FW so in case of power failure - // it doesn't wake up in off mode. - // persistence state will be restored on WiFi resume. - WiFi.persistent(false); - if (!WiFi.forceSleepBegin(sleepUs)) - { - // WIFI_OFF mode set by forceSleepBegin() - DEBUG_WIFI("core: error with forceSleepBegin()\n"); - WiFi.mode(before_off_mode); - WiFi.persistent(persistent); - return false; - } - - // WiFi is now in force-sleep mode - - if (state) - { - // finish filling state and process crc - - state->state.persistent = persistent; - state->state.mode = before_off_mode; - uint8_t i = 0; - for (auto& ntp: state->state.ntp) - { -#if LWIP_VERSION_MAJOR == 1 - ntp = sntp_getserver(i++); -#else - ntp = *sntp_getserver(i++); -#endif - } - i = 0; - for (auto& dns: state->state.dns) - dns = WiFi.dnsIP(i++); - state->crc = shutdownCRC(state); - DEBUG_WIFI("core: state is saved\n"); - } - return true; -} - -bool ESP8266WiFiGenericClass::resumeFromShutdown (WiFiState* state) -{ - if (wifi_fpm_get_sleep_type() != NONE_SLEEP_T) { - wifi_fpm_do_wakeup(); - wifi_fpm_close(); - } - - if (!state || shutdownCRC(state) != state->crc) - { - DEBUG_WIFI("core: resume: no state or bad crc\n"); - return false; - } - - persistent(state->state.persistent); - - if (!mode(state->state.mode)) - { - DEBUG_WIFI("core: resume: can't set wifi mode to %d\n", state->state.mode); - return false; - } - - if (state->state.mode & WIFI_STA) - { - IPAddress local(state->state.ip.ip); - if (local) - { - DEBUG_WIFI("core: resume: static address '%s'\n", local.toString().c_str()); - WiFi.config(state->state.ip.ip, state->state.ip.gw, state->state.ip.netmask, state->state.dns[0], state->state.dns[1]); - uint8_t i = 0; - for (CONST auto& ntp: state->state.ntp) - { - IPAddress ip(ntp); - if (ip.isSet()) - { - DEBUG_WIFI("core: resume: start SNTP, server='%s'\n", ip.toString().c_str()); - sntp_setserver(i++, &ntp); - } - } - } - // state->state.fwconfig.bssid is not real bssid (it's what user may have provided when bssid_set==1) - if (WiFi.begin((const char*)state->state.fwconfig.ssid, - (const char*)state->state.fwconfig.password, - state->state.channel, - nullptr/*(const uint8_t*)state->state.fwconfig.bssid*/, // <- try with gw's mac address? - true) == WL_CONNECT_FAILED) - { - DEBUG_WIFI("core: resume: WiFi.begin failed\n"); - return false; - } - } - - if (state->state.mode & WIFI_AP) - { - DEBUG_WIFI("core: resume AP mode TODO\n"); - return false; - } - - // success, invalidate saved state - state->crc++; - - return true; -} - -//meant to be called from user-defined ::preinit() -void ESP8266WiFiGenericClass::preinitWiFiOff () { - // https://github.com/esp8266/Arduino/issues/2111#issuecomment-224251391 - // WiFi.persistent(false); - // WiFi.mode(WIFI_OFF); - // WiFi.forceSleepBegin(); - - //WiFi.mode(WIFI_OFF) equivalent: - // datasheet: - // Set Wi-Fi working mode to Station mode, SoftAP - // or Station + SoftAP, and do not update flash - // (not persistent) - wifi_set_opmode_current(WIFI_OFF); - - //WiFi.forceSleepBegin(/*default*/0) equivalent: - // sleep forever until wifi_fpm_do_wakeup() is called - wifi_fpm_set_sleep_type(MODEM_SLEEP_T); - wifi_fpm_open(); - wifi_fpm_do_sleep(0xFFFFFFF); - - // use WiFi.forceSleepWake() to wake WiFi up -} diff --git a/extras/ESP8266WiFi_nossl_noleak/src/ESP8266WiFiGeneric.h b/extras/ESP8266WiFi_nossl_noleak/src/ESP8266WiFiGeneric.h deleted file mode 100644 index 675fceb..0000000 --- a/extras/ESP8266WiFi_nossl_noleak/src/ESP8266WiFiGeneric.h +++ /dev/null @@ -1,124 +0,0 @@ -/* - ESP8266WiFiGeneric.h - esp8266 Wifi support. - Based on WiFi.h from Ardiono WiFi shield library. - Copyright (c) 2011-2014 Arduino. All right reserved. - Modified by Ivan Grokhotkov, December 2014 - Reworked by Markus Sattler, December 2015 - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef ESP8266WIFIGENERIC_H_ -#define ESP8266WIFIGENERIC_H_ - -#include "ESP8266WiFiType.h" -#include -#include - -#ifdef DEBUG_ESP_WIFI -#ifdef DEBUG_ESP_PORT -#define DEBUG_WIFI_GENERIC(fmt, ...) DEBUG_ESP_PORT.printf_P( (PGM_P)PSTR(fmt), ##__VA_ARGS__ ) -#endif -#endif - -#ifndef DEBUG_WIFI_GENERIC -#define DEBUG_WIFI_GENERIC(...) do { (void)0; } while (0) -#endif - -struct WiFiEventHandlerOpaque; -typedef std::shared_ptr WiFiEventHandler; - -typedef void (*WiFiEventCb)(WiFiEvent_t); - -struct WiFiState; - -class ESP8266WiFiGenericClass { - // ---------------------------------------------------------------------------------------------- - // -------------------------------------- Generic WiFi function --------------------------------- - // ---------------------------------------------------------------------------------------------- - - public: - ESP8266WiFiGenericClass(); - - // Note: this function is deprecated. Use one of the functions below instead. - void onEvent(WiFiEventCb cb, WiFiEvent_t event = WIFI_EVENT_ANY) __attribute__((deprecated)); - - // Subscribe to specific event and get event information as an argument to the callback - WiFiEventHandler onStationModeConnected(std::function); - WiFiEventHandler onStationModeDisconnected(std::function); - WiFiEventHandler onStationModeAuthModeChanged(std::function); - WiFiEventHandler onStationModeGotIP(std::function); - WiFiEventHandler onStationModeDHCPTimeout(std::function); - WiFiEventHandler onSoftAPModeStationConnected(std::function); - WiFiEventHandler onSoftAPModeStationDisconnected(std::function); - WiFiEventHandler onSoftAPModeProbeRequestReceived(std::function); - WiFiEventHandler onWiFiModeChange(std::function); - - int32_t channel(void); - - bool setSleepMode(WiFiSleepType_t type, uint8_t listenInterval = 0); - - WiFiSleepType_t getSleepMode(); - uint8_t getListenInterval (); - bool isSleepLevelMax (); - - bool setPhyMode(WiFiPhyMode_t mode); - WiFiPhyMode_t getPhyMode(); - - void setOutputPower(float dBm); - - void persistent(bool persistent); - - bool mode(WiFiMode_t, WiFiState* state = nullptr); - WiFiMode_t getMode(); - - bool enableSTA(bool enable); - bool enableAP(bool enable); - - bool forceSleepBegin(uint32 sleepUs = 0); - bool forceSleepWake(); - - static uint32_t shutdownCRC (const WiFiState* state); - static bool shutdownValidCRC (const WiFiState* state); - static void preinitWiFiOff (); //meant to be called in user-defined preinit() - - protected: - static bool _persistent; - static WiFiMode_t _forceSleepLastMode; - - static void _eventCallback(void *event); - - // called by WiFi.mode(SHUTDOWN/RESTORE, state) - // - sleepUs is WiFi.forceSleepBegin() parameter, 0 = forever - // - saveState is the user's state to hold configuration on restore - bool shutdown (uint32 sleepUs = 0, WiFiState* stateSave = nullptr); - bool resumeFromShutdown (WiFiState* savedState = nullptr); - - // ---------------------------------------------------------------------------------------------- - // ------------------------------------ Generic Network function -------------------------------- - // ---------------------------------------------------------------------------------------------- - - public: - int hostByName(const char* aHostname, IPAddress& aResult); - int hostByName(const char* aHostname, IPAddress& aResult, uint32_t timeout_ms); - bool getPersistent(); - - protected: - friend class ESP8266WiFiSTAClass; - friend class ESP8266WiFiScanClass; - friend class ESP8266WiFiAPClass; -}; - -#endif /* ESP8266WIFIGENERIC_H_ */ diff --git a/extras/ESP8266WiFi_nossl_noleak/src/ESP8266WiFiMulti.cpp b/extras/ESP8266WiFi_nossl_noleak/src/ESP8266WiFiMulti.cpp deleted file mode 100644 index 4f9c9dc..0000000 --- a/extras/ESP8266WiFi_nossl_noleak/src/ESP8266WiFiMulti.cpp +++ /dev/null @@ -1,269 +0,0 @@ -/** - * - * @file ESP8266WiFiMulti.cpp - * @date 16.05.2015 - * @author Markus Sattler - * - * Copyright (c) 2015 Markus Sattler. All rights reserved. - * This file is part of the esp8266 core for Arduino environment. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#include "ESP8266WiFiMulti.h" -#include -#include - -ESP8266WiFiMulti::ESP8266WiFiMulti() { -} - -ESP8266WiFiMulti::~ESP8266WiFiMulti() { - APlistClean(); -} - -bool ESP8266WiFiMulti::addAP(const char* ssid, const char *passphrase) { - return APlistAdd(ssid, passphrase); -} - -void ESP8266WiFiMulti::cleanAPlist(void) { - APlistClean(); -} - -bool ESP8266WiFiMulti::existsAP(const char* ssid, const char *passphrase) { - return APlistExists(ssid, passphrase); -} - -wl_status_t ESP8266WiFiMulti::run(void) { - - wl_status_t status = WiFi.status(); - if(status == WL_DISCONNECTED || status == WL_NO_SSID_AVAIL || status == WL_IDLE_STATUS || status == WL_CONNECT_FAILED) { - - int8_t scanResult = WiFi.scanComplete(); - - if(scanResult == WIFI_SCAN_RUNNING) { - // scan is running, do nothing yet - status = WL_NO_SSID_AVAIL; - return status; - } - - if(scanResult == 0) { - // scan done, no ssids found. Start another scan. - DEBUG_WIFI_MULTI("[WIFI] scan done\n"); - DEBUG_WIFI_MULTI("[WIFI] no networks found\n"); - WiFi.scanDelete(); - DEBUG_WIFI_MULTI("\n\n"); - delay(0); - WiFi.disconnect(); - DEBUG_WIFI_MULTI("[WIFI] start scan\n"); - // scan wifi async mode - WiFi.scanNetworks(true); - return status; - } - - if(scanResult > 0) { - // scan done, analyze - WifiAPEntry bestNetwork { NULL, NULL }; - int bestNetworkDb = INT_MIN; - uint8 bestBSSID[6]; - int32_t bestChannel; - - DEBUG_WIFI_MULTI("[WIFI] scan done\n"); - delay(0); - - DEBUG_WIFI_MULTI("[WIFI] %d networks found\n", scanResult); - for(int8_t i = 0; i < scanResult; ++i) { - - String ssid_scan; - int32_t rssi_scan; - uint8_t sec_scan; - uint8_t* BSSID_scan; - int32_t chan_scan; - bool hidden_scan; - - WiFi.getNetworkInfo(i, ssid_scan, sec_scan, rssi_scan, BSSID_scan, chan_scan, hidden_scan); - - bool known = false; - for(auto entry : APlist) { - if(ssid_scan == entry.ssid) { // SSID match - known = true; - if(rssi_scan > bestNetworkDb) { // best network - if(sec_scan == ENC_TYPE_NONE || entry.passphrase) { // check for passphrase if not open wlan - bestNetworkDb = rssi_scan; - bestChannel = chan_scan; - bestNetwork = entry; - memcpy((void*) &bestBSSID, (void*) BSSID_scan, sizeof(bestBSSID)); - } - } - break; - } - } - - if(known) { - DEBUG_WIFI_MULTI(" ---> "); - } else { - DEBUG_WIFI_MULTI(" "); - } - - DEBUG_WIFI_MULTI(" %d: [%d][%02X:%02X:%02X:%02X:%02X:%02X] %s (%d) %c\n", i, chan_scan, BSSID_scan[0], BSSID_scan[1], BSSID_scan[2], BSSID_scan[3], BSSID_scan[4], BSSID_scan[5], ssid_scan.c_str(), rssi_scan, (sec_scan == ENC_TYPE_NONE) ? ' ' : '*'); - delay(0); - } - - // clean up ram - WiFi.scanDelete(); - - DEBUG_WIFI_MULTI("\n\n"); - delay(0); - - if(bestNetwork.ssid) { - DEBUG_WIFI_MULTI("[WIFI] Connecting BSSID: %02X:%02X:%02X:%02X:%02X:%02X SSID: %s Channel: %d (%d)\n", bestBSSID[0], bestBSSID[1], bestBSSID[2], bestBSSID[3], bestBSSID[4], bestBSSID[5], bestNetwork.ssid, bestChannel, bestNetworkDb); - - WiFi.begin(bestNetwork.ssid, bestNetwork.passphrase, bestChannel, bestBSSID); - status = WiFi.status(); - - static const uint32_t connectTimeout = 5000; //5s timeout - - auto startTime = millis(); - // wait for connection, fail, or timeout - while(status != WL_CONNECTED && status != WL_NO_SSID_AVAIL && status != WL_CONNECT_FAILED && (millis() - startTime) <= connectTimeout) { - delay(10); - status = WiFi.status(); - } - -#ifdef DEBUG_ESP_WIFI - IPAddress ip; - uint8_t * mac; - switch(status) { - case WL_CONNECTED: - ip = WiFi.localIP(); - mac = WiFi.BSSID(); - DEBUG_WIFI_MULTI("[WIFI] Connecting done.\n"); - DEBUG_WIFI_MULTI("[WIFI] SSID: %s\n", WiFi.SSID().c_str()); - DEBUG_WIFI_MULTI("[WIFI] IP: %d.%d.%d.%d\n", ip[0], ip[1], ip[2], ip[3]); - DEBUG_WIFI_MULTI("[WIFI] MAC: %02X:%02X:%02X:%02X:%02X:%02X\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); - DEBUG_WIFI_MULTI("[WIFI] Channel: %d\n", WiFi.channel()); - break; - case WL_NO_SSID_AVAIL: - DEBUG_WIFI_MULTI("[WIFI] Connecting Failed AP not found.\n"); - break; - case WL_CONNECT_FAILED: - DEBUG_WIFI_MULTI("[WIFI] Connecting Failed.\n"); - break; - default: - DEBUG_WIFI_MULTI("[WIFI] Connecting Failed (%d).\n", status); - break; - } -#endif - } else { - DEBUG_WIFI_MULTI("[WIFI] no matching wifi found!\n"); - } - - return status; - } - - - // scan failed, or some other condition not handled above. Start another scan. - DEBUG_WIFI_MULTI("[WIFI] delete old wifi config...\n"); - WiFi.disconnect(); - - DEBUG_WIFI_MULTI("[WIFI] start scan\n"); - // scan wifi async mode - WiFi.scanNetworks(true); - } - return status; -} - -// ################################################################################## - -bool ESP8266WiFiMulti::APlistAdd(const char* ssid, const char *passphrase) { - - WifiAPEntry newAP; - - if(!ssid || *ssid == 0x00 || strlen(ssid) > 32) { - // fail SSID too long or missing! - DEBUG_WIFI_MULTI("[WIFI][APlistAdd] no ssid or ssid too long\n"); - return false; - } - - //for passphrase, max is 63 ascii + null. For psk, 64hex + null. - if(passphrase && strlen(passphrase) > 64) { - // fail passphrase too long! - DEBUG_WIFI_MULTI("[WIFI][APlistAdd] passphrase too long\n"); - return false; - } - - if(APlistExists(ssid, passphrase)) { - DEBUG_WIFI_MULTI("[WIFI][APlistAdd] SSID: %s already exists\n", ssid); - return true; - } - - newAP.ssid = strdup(ssid); - - if(!newAP.ssid) { - DEBUG_WIFI_MULTI("[WIFI][APlistAdd] fail newAP.ssid == 0\n"); - return false; - } - - if(passphrase) { - newAP.passphrase = strdup(passphrase); - } else { - newAP.passphrase = strdup(""); - } - - if(!newAP.passphrase) { - DEBUG_WIFI_MULTI("[WIFI][APlistAdd] fail newAP.passphrase == 0\n"); - free(newAP.ssid); - return false; - } - - APlist.push_back(newAP); - DEBUG_WIFI_MULTI("[WIFI][APlistAdd] add SSID: %s\n", newAP.ssid); - return true; -} - -bool ESP8266WiFiMulti::APlistExists(const char* ssid, const char *passphrase) { - if(!ssid || *ssid == 0x00 || strlen(ssid) > 32) { - // fail SSID too long or missing! - DEBUG_WIFI_MULTI("[WIFI][APlistExists] no ssid or ssid too long\n"); - return false; - } - for(auto entry : APlist) { - if(!strcmp(entry.ssid, ssid)) { - if(!passphrase) { - if(!strcmp(entry.passphrase, "")) { - return true; - } - } else { - if(!strcmp(entry.passphrase, passphrase)) { - return true; - } - } - } - } - return false; -} - -void ESP8266WiFiMulti::APlistClean(void) { - for(auto entry : APlist) { - if(entry.ssid) { - free(entry.ssid); - } - if(entry.passphrase) { - free(entry.passphrase); - } - } - APlist.clear(); -} - diff --git a/extras/ESP8266WiFi_nossl_noleak/src/ESP8266WiFiMulti.h b/extras/ESP8266WiFi_nossl_noleak/src/ESP8266WiFiMulti.h deleted file mode 100644 index 31144ae..0000000 --- a/extras/ESP8266WiFi_nossl_noleak/src/ESP8266WiFiMulti.h +++ /dev/null @@ -1,70 +0,0 @@ -/** - * - * @file ESP8266WiFiMulti.h - * @date 16.05.2015 - * @author Markus Sattler - * - * Copyright (c) 2015 Markus Sattler. All rights reserved. - * This file is part of the esp8266 core for Arduino environment. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - - -#ifndef WIFICLIENTMULTI_H_ -#define WIFICLIENTMULTI_H_ - -#include "ESP8266WiFi.h" -#include - -#ifdef DEBUG_ESP_WIFI -#ifdef DEBUG_ESP_PORT -#define DEBUG_WIFI_MULTI(fmt, ...) DEBUG_ESP_PORT.printf_P( (PGM_P)PSTR(fmt), ##__VA_ARGS__ ) -#endif -#endif - -#ifndef DEBUG_WIFI_MULTI -#define DEBUG_WIFI_MULTI(...) do { (void)0; } while (0) -#endif - -struct WifiAPEntry { - char * ssid; - char * passphrase; -}; - -typedef std::vector WifiAPlist; - -class ESP8266WiFiMulti { - public: - ESP8266WiFiMulti(); - ~ESP8266WiFiMulti(); - - bool addAP(const char* ssid, const char *passphrase = NULL); - bool existsAP(const char* ssid, const char *passphrase = NULL); - - wl_status_t run(void); - - void cleanAPlist(void); - - private: - WifiAPlist APlist; - bool APlistAdd(const char* ssid, const char *passphrase = NULL); - bool APlistExists(const char* ssid, const char *passphrase = NULL); - void APlistClean(void); - -}; - -#endif /* WIFICLIENTMULTI_H_ */ diff --git a/extras/ESP8266WiFi_nossl_noleak/src/ESP8266WiFiSTA.cpp b/extras/ESP8266WiFi_nossl_noleak/src/ESP8266WiFiSTA.cpp deleted file mode 100644 index 2aeb61f..0000000 --- a/extras/ESP8266WiFi_nossl_noleak/src/ESP8266WiFiSTA.cpp +++ /dev/null @@ -1,784 +0,0 @@ -/* - ESP8266WiFiSTA.cpp - WiFi library for esp8266 - - Copyright (c) 2014 Ivan Grokhotkov. All rights reserved. - This file is part of the esp8266 core for Arduino environment. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - Reworked on 28 Dec 2015 by Markus Sattler - - */ - -#include "ESP8266WiFi.h" -#include "ESP8266WiFiGeneric.h" -#include "ESP8266WiFiSTA.h" -#include "PolledTimeout.h" - -#include "c_types.h" -#include "ets_sys.h" -#include "os_type.h" -#include "osapi.h" -#include "mem.h" -#include "user_interface.h" -#include "smartconfig.h" - -extern "C" { -#include "lwip/err.h" -#include "lwip/dns.h" -#include "lwip/dhcp.h" -#include "lwip/init.h" // LWIP_VERSION_ -#if LWIP_IPV6 -#include "lwip/netif.h" // struct netif -#endif -} - -#include "debug.h" - -extern "C" void esp_schedule(); -extern "C" void esp_yield(); - -// ----------------------------------------------------------------------------------------------------------------------- -// ---------------------------------------------------- Private functions ------------------------------------------------ -// ----------------------------------------------------------------------------------------------------------------------- - -static bool sta_config_equal(const station_config& lhs, const station_config& rhs); - - -/** - * compare two STA configurations - * @param lhs station_config - * @param rhs station_config - * @return equal - */ -static bool sta_config_equal(const station_config& lhs, const station_config& rhs) { - -#ifdef NONOSDK3V0 - static_assert(sizeof(station_config) == 116, "struct station_config has changed, please update comparison function"); -#else - static_assert(sizeof(station_config) == 112, "struct station_config has changed, please update comparison function"); -#endif - - if(strncmp(reinterpret_cast(lhs.ssid), reinterpret_cast(rhs.ssid), sizeof(lhs.ssid)) != 0) { - return false; - } - - //in case of password, use strncmp with size 64 to cover 64byte psk case (no null term) - if(strncmp(reinterpret_cast(lhs.password), reinterpret_cast(rhs.password), sizeof(lhs.password)) != 0) { - return false; - } - - if(lhs.bssid_set != rhs.bssid_set) { - return false; - } - - if(lhs.bssid_set) { - if(memcmp(lhs.bssid, rhs.bssid, 6) != 0) { - return false; - } - } - - if(lhs.threshold.rssi != rhs.threshold.rssi) { - return false; - } - - if(lhs.threshold.authmode != rhs.threshold.authmode) { - return false; - } - -#ifdef NONOSDK3V0 - if (lhs.open_and_wep_mode_disable != rhs.open_and_wep_mode_disable) { - return false; - } -#endif - - return true; -} - -// ----------------------------------------------------------------------------------------------------------------------- -// ---------------------------------------------------- STA function ----------------------------------------------------- -// ----------------------------------------------------------------------------------------------------------------------- - -bool ESP8266WiFiSTAClass::_useStaticIp = false; -bool ESP8266WiFiSTAClass::_useInsecureWEP = false; - -/** - * Start Wifi connection - * if passphrase is set the most secure supported mode will be automatically selected - * @param ssid const char* Pointer to the SSID string. - * @param passphrase const char * Optional. Passphrase. Valid characters in a passphrase must be between ASCII 32-126 (decimal). - * @param bssid uint8_t[6] Optional. BSSID / MAC of AP - * @param channel Optional. Channel of AP - * @param connect Optional. call connect - * @return - */ -wl_status_t ESP8266WiFiSTAClass::begin(const char* ssid, const char *passphrase, int32_t channel, const uint8_t* bssid, bool connect) { - - if(!WiFi.enableSTA(true)) { - // enable STA failed - return WL_CONNECT_FAILED; - } - - if(!ssid || *ssid == 0x00 || strlen(ssid) > 32) { - // fail SSID too long or missing! - return WL_CONNECT_FAILED; - } - - int passphraseLen = passphrase == nullptr ? 0 : strlen(passphrase); - if(passphraseLen > 64) { - // fail passphrase too long! - return WL_CONNECT_FAILED; - } - - struct station_config conf; - conf.threshold.authmode = (passphraseLen == 0) ? AUTH_OPEN : (_useInsecureWEP ? AUTH_WEP : AUTH_WPA_PSK); - - if(strlen(ssid) == 32) - memcpy(reinterpret_cast(conf.ssid), ssid, 32); //copied in without null term - else - strcpy(reinterpret_cast(conf.ssid), ssid); - - if(passphrase) { - if (passphraseLen == 64) // it's not a passphrase, is the PSK, which is copied into conf.password without null term - memcpy(reinterpret_cast(conf.password), passphrase, 64); - else - strcpy(reinterpret_cast(conf.password), passphrase); - } else { - *conf.password = 0; - } - - conf.threshold.rssi = -127; -#ifdef NONOSDK3V0 - conf.open_and_wep_mode_disable = !(_useInsecureWEP || *conf.password == 0); -#endif - - if(bssid) { - conf.bssid_set = 1; - memcpy((void *) &conf.bssid[0], (void *) bssid, 6); - } else { - conf.bssid_set = 0; - } - - struct station_config conf_compare; - if(WiFi._persistent){ - wifi_station_get_config_default(&conf_compare); - } - else { - wifi_station_get_config(&conf_compare); - } - - if(sta_config_equal(conf_compare, conf)) { - DEBUGV("sta config unchanged"); - } - else { - ETS_UART_INTR_DISABLE(); - - if(WiFi._persistent) { - wifi_station_set_config(&conf); - } else { - wifi_station_set_config_current(&conf); - } - - ETS_UART_INTR_ENABLE(); - } - - ETS_UART_INTR_DISABLE(); - if(connect) { - wifi_station_connect(); - } - ETS_UART_INTR_ENABLE(); - - if(channel > 0 && channel <= 13) { - wifi_set_channel(channel); - } - - if(!_useStaticIp) { - wifi_station_dhcpc_start(); - } - - return status(); -} - -wl_status_t ESP8266WiFiSTAClass::begin(char* ssid, char *passphrase, int32_t channel, const uint8_t* bssid, bool connect) { - return begin((const char*) ssid, (const char*) passphrase, channel, bssid, connect); -} - -wl_status_t ESP8266WiFiSTAClass::begin(const String& ssid, const String& passphrase, int32_t channel, const uint8_t* bssid, bool connect) { - return begin(ssid.c_str(), passphrase.c_str(), channel, bssid, connect); -} - -/** - * Use to connect to SDK config. - * @return wl_status_t - */ -wl_status_t ESP8266WiFiSTAClass::begin() { - - if(!WiFi.enableSTA(true)) { - // enable STA failed - return WL_CONNECT_FAILED; - } - - ETS_UART_INTR_DISABLE(); - wifi_station_connect(); - ETS_UART_INTR_ENABLE(); - - if(!_useStaticIp) { - wifi_station_dhcpc_start(); - } - return status(); -} - -/** - * Change IP configuration settings disabling the dhcp client - * @param local_ip Static ip configuration - * @param gateway Static gateway configuration - * @param subnet Static Subnet mask - * @param dns1 Static DNS server 1 - * @param dns2 Static DNS server 2 - */ - -#if LWIP_VERSION_MAJOR != 1 -/* - About the following call in the end of ESP8266WiFiSTAClass::config(): - netif_set_addr(eagle_lwip_getif(STATION_IF), &info.ip, &info.netmask, &info.gw); - - With lwip2, it is needed to trigger IP address change. - Recall: when lwip2 is enabled, lwip1 api is still used by espressif firmware - https://github.com/d-a-v/esp82xx-nonos-linklayer/tree/25d5e8186f710a230221021cba97727dbfdfd953#how-it-works - - We need first to disable the lwIP API redirection for netif_set_addr() so lwip1's call will be linked: - https://github.com/d-a-v/esp82xx-nonos-linklayer/blob/25d5e8186f710a230221021cba97727dbfdfd953/glue-lwip/arch/cc.h#L122 - - We also need to declare its prototype using ip4_addr_t instead of ip_addr_t because lwIP-1.x never has IPv6. - No need to worry about this #undef, this call is only needed in lwip2, and never used in arduino core code. - */ -#undef netif_set_addr // need to call lwIP-v1.4 netif_set_addr() -extern "C" struct netif* eagle_lwip_getif (int netif_index); -extern "C" void netif_set_addr (struct netif* netif, ip4_addr_t* ip, ip4_addr_t* netmask, ip4_addr_t* gw); -#endif - -bool ESP8266WiFiSTAClass::config(IPAddress local_ip, IPAddress arg1, IPAddress arg2, IPAddress arg3, IPAddress dns2) { - - if(!WiFi.enableSTA(true)) { - return false; - } - - //ESP argument order is: ip, gateway, subnet, dns1 - //Arduino arg order is: ip, dns, gateway, subnet. - - //first, check whether dhcp should be used, which is when ip == 0 && gateway == 0 && subnet == 0. - bool espOrderUseDHCP = (local_ip == 0U && arg1 == 0U && arg2 == 0U); - bool arduinoOrderUseDHCP = (local_ip == 0U && arg2 == 0U && arg3 == 0U); - if (espOrderUseDHCP || arduinoOrderUseDHCP) { - _useStaticIp = false; - wifi_station_dhcpc_start(); - return true; - } - - //To allow compatibility, check first octet of 3rd arg. If 255, interpret as ESP order, otherwise Arduino order. - IPAddress gateway = arg1; - IPAddress subnet = arg2; - IPAddress dns1 = arg3; - - if(subnet[0] != 255) - { - //octet is not 255 => interpret as Arduino order - gateway = arg2; - subnet = arg3[0] == 0 ? IPAddress(255,255,255,0) : arg3; //arg order is arduino and 4th arg not given => assign it arduino default - dns1 = arg1; - } - - // check whether all is IPv4 (or gateway not set) - if (!(local_ip.isV4() && subnet.isV4() && (!gateway.isSet() || gateway.isV4()))) { - return false; - } - - //ip and gateway must be in the same subnet - if((local_ip.v4() & subnet.v4()) != (gateway.v4() & subnet.v4())) { - return false; - } - -#if LWIP_VERSION_MAJOR != 1 && !CORE_MOCK - // get current->previous IP address - // (check below) - struct ip_info previp; - wifi_get_ip_info(STATION_IF, &previp); -#endif - - struct ip_info info; - info.ip.addr = local_ip.v4(); - info.gw.addr = gateway.v4(); - info.netmask.addr = subnet.v4(); - - wifi_station_dhcpc_stop(); - if(wifi_set_ip_info(STATION_IF, &info)) { - _useStaticIp = true; - } else { - return false; - } - - if(dns1.isSet()) { - // Set DNS1-Server - dns_setserver(0, dns1); - } - - if(dns2.isSet()) { - // Set DNS2-Server - dns_setserver(1, dns2); - } - -#if LWIP_VERSION_MAJOR != 1 && !CORE_MOCK - // trigger address change by calling lwIP-v1.4 api - // (see explanation above) - // only when ip is already set by other mean (generally dhcp) - if (previp.ip.addr != 0 && previp.ip.addr != info.ip.addr) - netif_set_addr(eagle_lwip_getif(STATION_IF), &info.ip, &info.netmask, &info.gw); -#endif - - return true; -} - -/** - * will force a disconnect an then start reconnecting to AP - * @return ok - */ -bool ESP8266WiFiSTAClass::reconnect() { - if((WiFi.getMode() & WIFI_STA) != 0) { - if(wifi_station_disconnect()) { - return wifi_station_connect(); - } - } - return false; -} - -/** - * Disconnect from the network - * @param wifioff - * @return one value of wl_status_t enum - */ -bool ESP8266WiFiSTAClass::disconnect(bool wifioff) { - bool ret = false; - struct station_config conf; - *conf.ssid = 0; - *conf.password = 0; - - // API Reference: wifi_station_disconnect() need to be called after system initializes and the ESP8266 Station mode is enabled. - if (WiFi.getMode() & WIFI_STA) - ret = wifi_station_disconnect(); - else - ret = true; - - ETS_UART_INTR_DISABLE(); - if(WiFi._persistent) { - wifi_station_set_config(&conf); - } else { - wifi_station_set_config_current(&conf); - } - - ETS_UART_INTR_ENABLE(); - - if(wifioff) { - WiFi.enableSTA(false); - } - - return ret; -} - -/** - * is STA interface connected? - * @return true if STA is connected to an AD - */ -bool ESP8266WiFiSTAClass::isConnected() { - return (status() == WL_CONNECTED); -} - - -/** - * Setting the ESP8266 station to connect to the AP (which is recorded) - * automatically or not when powered on. Enable auto-connect by default. - * @param autoConnect bool - * @return if saved - */ -bool ESP8266WiFiSTAClass::setAutoConnect(bool autoConnect) { - bool ret; - ETS_UART_INTR_DISABLE(); - ret = wifi_station_set_auto_connect(autoConnect); - ETS_UART_INTR_ENABLE(); - return ret; -} - -/** - * Checks if ESP8266 station mode will connect to AP - * automatically or not when it is powered on. - * @return auto connect - */ -bool ESP8266WiFiSTAClass::getAutoConnect() { - return (wifi_station_get_auto_connect() != 0); -} - -/** - * Set whether reconnect or not when the ESP8266 station is disconnected from AP. - * @param autoReconnect - * @return - */ -bool ESP8266WiFiSTAClass::setAutoReconnect(bool autoReconnect) { - return wifi_station_set_reconnect_policy(autoReconnect); -} - -/** - * get whether reconnect or not when the ESP8266 station is disconnected from AP. - * @return autoreconnect - */ -bool ESP8266WiFiSTAClass::getAutoReconnect() { - return wifi_station_get_reconnect_policy(); -} - -/** - * Wait for WiFi connection to reach a result - * returns the status reached or disconnect if STA is off - * @return wl_status_t or -1 on timeout - */ -int8_t ESP8266WiFiSTAClass::waitForConnectResult(unsigned long timeoutLength) { - //1 and 3 have STA enabled - if((wifi_get_opmode() & 1) == 0) { - return WL_DISCONNECTED; - } - using esp8266::polledTimeout::oneShot; - oneShot timeout(timeoutLength); // number of milliseconds to wait before returning timeout error - while(!timeout) { - yield(); - if(status() != WL_DISCONNECTED) { - return status(); - } - } - return -1; // -1 indicates timeout -} - -/** - * Get the station interface IP address. - * @return IPAddress station IP - */ -IPAddress ESP8266WiFiSTAClass::localIP() { - struct ip_info ip; - wifi_get_ip_info(STATION_IF, &ip); - return IPAddress(ip.ip.addr); -} - -/** - * Get the station interface MAC address. - * @param mac pointer to uint8_t array with length WL_MAC_ADDR_LENGTH - * @return pointer to uint8_t * - */ -uint8_t* ESP8266WiFiSTAClass::macAddress(uint8_t* mac) { - wifi_get_macaddr(STATION_IF, mac); - return mac; -} - -/** - * Get the station interface MAC address. - * @return String mac - */ -String ESP8266WiFiSTAClass::macAddress(void) { - uint8_t mac[6]; - char macStr[18] = { 0 }; - wifi_get_macaddr(STATION_IF, mac); - - sprintf(macStr, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); - return String(macStr); -} - -/** - * Get the interface subnet mask address. - * @return IPAddress subnetMask - */ -IPAddress ESP8266WiFiSTAClass::subnetMask() { - struct ip_info ip; - wifi_get_ip_info(STATION_IF, &ip); - return IPAddress(ip.netmask.addr); -} - -/** - * Get the gateway ip address. - * @return IPAddress gatewayIP - */ -IPAddress ESP8266WiFiSTAClass::gatewayIP() { - struct ip_info ip; - wifi_get_ip_info(STATION_IF, &ip); - return IPAddress(ip.gw.addr); -} - -/** - * Get the DNS ip address. - * @param dns_no - * @return IPAddress DNS Server IP - */ -IPAddress ESP8266WiFiSTAClass::dnsIP(uint8_t dns_no) { -#if LWIP_VERSION_MAJOR == 1 - ip_addr_t dns_ip = dns_getserver(dns_no); - return IPAddress(dns_ip.addr); -#else - return IPAddress(dns_getserver(dns_no)); -#endif -} - - -/** - * Get ESP8266 station DHCP hostname - * @return hostname - */ -String ESP8266WiFiSTAClass::hostname(void) { - return wifi_station_get_hostname(); -} - -/** - * Set ESP8266 station DHCP hostname - * @param aHostname max length:24 - * @return ok - */ -bool ESP8266WiFiSTAClass::hostname(const char* aHostname) { - /* - vvvv RFC952 vvvv - ASSUMPTIONS - 1. A "name" (Net, Host, Gateway, or Domain name) is a text string up - to 24 characters drawn from the alphabet (A-Z), digits (0-9), minus - sign (-), and period (.). Note that periods are only allowed when - they serve to delimit components of "domain style names". (See - RFC-921, "Domain Name System Implementation Schedule", for - background). No blank or space characters are permitted as part of a - name. No distinction is made between upper and lower case. The first - character must be an alpha character. The last character must not be - a minus sign or period. A host which serves as a GATEWAY should have - "-GATEWAY" or "-GW" as part of its name. Hosts which do not serve as - Internet gateways should not use "-GATEWAY" and "-GW" as part of - their names. A host which is a TAC should have "-TAC" as the last - part of its host name, if it is a DoD host. Single character names - or nicknames are not allowed. - ^^^^ RFC952 ^^^^ - - - 24 chars max - - only a..z A..Z 0..9 '-' - - no '-' as last char - */ - - size_t len = strlen(aHostname); - - if (len == 0 || len > 32) { - // nonos-sdk limit is 32 - // (dhcp hostname option minimum size is ~60) - DEBUG_WIFI_GENERIC("WiFi.(set)hostname(): empty or large(>32) name\n"); - return false; - } - - // check RFC compliance - bool compliant = (len <= 24); - for (size_t i = 0; compliant && i < len; i++) - if (!isalnum(aHostname[i]) && aHostname[i] != '-') - compliant = false; - if (aHostname[len - 1] == '-') - compliant = false; - - if (!compliant) { - DEBUG_WIFI_GENERIC("hostname '%s' is not compliant with RFC952\n", aHostname); - } - - bool ret = wifi_station_set_hostname(aHostname); - if (!ret) { - DEBUG_WIFI_GENERIC("WiFi.hostname(%s): wifi_station_set_hostname() failed\n", aHostname); - return false; - } - - // now we should inform dhcp server for this change, using lwip_renew() - // looping through all existing interface - // harmless for AP, also compatible with ethernet adapters (to come) - for (netif* intf = netif_list; intf; intf = intf->next) { - - // unconditionally update all known interfaces -#if LWIP_VERSION_MAJOR == 1 - intf->hostname = (char*)wifi_station_get_hostname(); -#else - intf->hostname = wifi_station_get_hostname(); -#endif - - if (netif_dhcp_data(intf) != nullptr) { - // renew already started DHCP leases - err_t lwipret = dhcp_renew(intf); - if (lwipret != ERR_OK) { - DEBUG_WIFI_GENERIC("WiFi.hostname(%s): lwIP error %d on interface %c%c (index %d)\n", - intf->hostname, (int)lwipret, intf->name[0], intf->name[1], intf->num); - ret = false; - } - } - } - - return ret && compliant; -} - -/** - * Return Connection status. - * @return one of the value defined in wl_status_t - * - */ -wl_status_t ESP8266WiFiSTAClass::status() { - station_status_t status = wifi_station_get_connect_status(); - - switch(status) { - case STATION_GOT_IP: - return WL_CONNECTED; - case STATION_NO_AP_FOUND: - return WL_NO_SSID_AVAIL; - case STATION_CONNECT_FAIL: - case STATION_WRONG_PASSWORD: - return WL_CONNECT_FAILED; - case STATION_IDLE: - return WL_IDLE_STATUS; - default: - return WL_DISCONNECTED; - } -} - -/** - * Return the current SSID associated with the network - * @return SSID - */ -String ESP8266WiFiSTAClass::SSID() const { - struct station_config conf; - wifi_station_get_config(&conf); - char tmp[33]; //ssid can be up to 32chars, => plus null term - memcpy(tmp, conf.ssid, sizeof(conf.ssid)); - tmp[32] = 0; //nullterm in case of 32 char ssid - return String(reinterpret_cast(tmp)); -} - -/** - * Return the current pre shared key associated with the network - * @return psk string - */ -String ESP8266WiFiSTAClass::psk() const { - struct station_config conf; - wifi_station_get_config(&conf); - char tmp[65]; //psk is 64 bytes hex => plus null term - memcpy(tmp, conf.password, sizeof(conf.password)); - tmp[64] = 0; //null term in case of 64 byte psk - return String(reinterpret_cast(tmp)); -} - -/** - * Return the current bssid / mac associated with the network if configured - * @return bssid uint8_t * - */ -uint8_t* ESP8266WiFiSTAClass::BSSID(void) { - static struct station_config conf; - wifi_station_get_config(&conf); - return reinterpret_cast(conf.bssid); -} - -/** - * Return the current bssid / mac associated with the network if configured - * @return String bssid mac - */ -String ESP8266WiFiSTAClass::BSSIDstr(void) { - struct station_config conf; - char mac[18] = { 0 }; - wifi_station_get_config(&conf); - sprintf(mac, "%02X:%02X:%02X:%02X:%02X:%02X", conf.bssid[0], conf.bssid[1], conf.bssid[2], conf.bssid[3], conf.bssid[4], conf.bssid[5]); - return String(mac); -} - -/** - * Return the current network RSSI. - * @return RSSI value - */ -int32_t ESP8266WiFiSTAClass::RSSI(void) { - return wifi_station_get_rssi(); -} - - - -// ----------------------------------------------------------------------------------------------------------------------- -// -------------------------------------------------- STA remote configure ----------------------------------------------- -// ----------------------------------------------------------------------------------------------------------------------- - -bool ESP8266WiFiSTAClass::_smartConfigStarted = false; -bool ESP8266WiFiSTAClass::_smartConfigDone = false; - -/** - * Start SmartConfig - */ -bool ESP8266WiFiSTAClass::beginSmartConfig() { - if(_smartConfigStarted) { - return false; - } - - if(!WiFi.enableSTA(true)) { - // enable STA failed - return false; - } - - if(smartconfig_start(reinterpret_cast(&ESP8266WiFiSTAClass::_smartConfigCallback), 1)) { - _smartConfigStarted = true; - _smartConfigDone = false; - return true; - } - return false; -} - - -/** - * Stop SmartConfig - */ -bool ESP8266WiFiSTAClass::stopSmartConfig() { - if(!_smartConfigStarted) { - return true; - } - - if(smartconfig_stop()) { - _smartConfigStarted = false; - return true; - } - return false; -} - -/** - * Query SmartConfig status, to decide when stop config - * @return smartConfig Done - */ -bool ESP8266WiFiSTAClass::smartConfigDone() { - if(!_smartConfigStarted) { - return false; - } - - return _smartConfigDone; -} - - -/** - * _smartConfigCallback - * @param st - * @param result - */ -void ESP8266WiFiSTAClass::_smartConfigCallback(uint32_t st, void* result) { - sc_status status = (sc_status) st; - if(status == SC_STATUS_LINK) { - station_config* sta_conf = reinterpret_cast(result); - - wifi_station_set_config(sta_conf); - wifi_station_disconnect(); - wifi_station_connect(); - - _smartConfigDone = true; - } else if(status == SC_STATUS_LINK_OVER) { - WiFi.stopSmartConfig(); - } -} diff --git a/extras/ESP8266WiFi_nossl_noleak/src/ESP8266WiFiSTA.h b/extras/ESP8266WiFi_nossl_noleak/src/ESP8266WiFiSTA.h deleted file mode 100644 index b3fd9ce..0000000 --- a/extras/ESP8266WiFi_nossl_noleak/src/ESP8266WiFiSTA.h +++ /dev/null @@ -1,114 +0,0 @@ -/* - ESP8266WiFiSTA.h - esp8266 Wifi support. - Based on WiFi.h from Ardiono WiFi shield library. - Copyright (c) 2011-2014 Arduino. All right reserved. - Modified by Ivan Grokhotkov, December 2014 - Reworked by Markus Sattler, December 2015 - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef ESP8266WIFISTA_H_ -#define ESP8266WIFISTA_H_ - - -#include "ESP8266WiFiType.h" -#include "ESP8266WiFiGeneric.h" -#include "user_interface.h" - - -class ESP8266WiFiSTAClass { - // ---------------------------------------------------------------------------------------------- - // ---------------------------------------- STA function ---------------------------------------- - // ---------------------------------------------------------------------------------------------- - - public: - - wl_status_t begin(const char* ssid, const char *passphrase = NULL, int32_t channel = 0, const uint8_t* bssid = NULL, bool connect = true); - wl_status_t begin(char* ssid, char *passphrase = NULL, int32_t channel = 0, const uint8_t* bssid = NULL, bool connect = true); - wl_status_t begin(const String& ssid, const String& passphrase = emptyString, int32_t channel = 0, const uint8_t* bssid = NULL, bool connect = true); - wl_status_t begin(); - - //The argument order for ESP is not the same as for Arduino. However, there is compatibility code under the hood - //to detect Arduino arg order, and handle it correctly. Be aware that the Arduino default value handling doesn't - //work here (see Arduino docs for gway/subnet defaults). In other words: at least 3 args must always be given. - bool config(IPAddress local_ip, IPAddress gateway, IPAddress subnet, IPAddress dns1 = (uint32_t)0x00000000, IPAddress dns2 = (uint32_t)0x00000000); - - bool reconnect(); - bool disconnect(bool wifioff = false); - - bool isConnected(); - - bool setAutoConnect(bool autoConnect); - bool getAutoConnect(); - - bool setAutoReconnect(bool autoReconnect); - bool getAutoReconnect(); - - int8_t waitForConnectResult(unsigned long timeoutLength = 60000); - - // STA network info - IPAddress localIP(); - - uint8_t * macAddress(uint8_t* mac); - String macAddress(); - - IPAddress subnetMask(); - IPAddress gatewayIP(); - IPAddress dnsIP(uint8_t dns_no = 0); - - String hostname(); - bool hostname(const String& aHostname) { return hostname(aHostname.c_str()); } - bool hostname(const char* aHostname); - - // STA WiFi info - wl_status_t status(); - String SSID() const; - String psk() const; - - uint8_t * BSSID(); - String BSSIDstr(); - - int32_t RSSI(); - - static void enableInsecureWEP (bool enable = true) { _useInsecureWEP = enable; } - - protected: - - static bool _useStaticIp; - static bool _useInsecureWEP; - - // ---------------------------------------------------------------------------------------------- - // ------------------------------------ STA remote configure ----------------------------------- - // ---------------------------------------------------------------------------------------------- - - public: - - bool beginWPSConfig(void); - bool beginSmartConfig(); - bool stopSmartConfig(); - bool smartConfigDone(); - - protected: - - static bool _smartConfigStarted; - static bool _smartConfigDone; - - static void _smartConfigCallback(uint32_t status, void* result); - -}; - - -#endif /* ESP8266WIFISTA_H_ */ diff --git a/extras/ESP8266WiFi_nossl_noleak/src/ESP8266WiFiScan.cpp b/extras/ESP8266WiFi_nossl_noleak/src/ESP8266WiFiScan.cpp deleted file mode 100644 index e225257..0000000 --- a/extras/ESP8266WiFi_nossl_noleak/src/ESP8266WiFiScan.cpp +++ /dev/null @@ -1,343 +0,0 @@ -/* - ESP8266WiFiScan.cpp - WiFi library for esp8266 - - Copyright (c) 2014 Ivan Grokhotkov. All rights reserved. - This file is part of the esp8266 core for Arduino environment. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - Reworked on 28 Dec 2015 by Markus Sattler - - */ - -#include "ESP8266WiFi.h" -#include "ESP8266WiFiGeneric.h" -#include "ESP8266WiFiScan.h" - -extern "C" { -#include "c_types.h" -#include "ets_sys.h" -#include "os_type.h" -#include "osapi.h" -#include "mem.h" -#include "user_interface.h" -} - -#include "debug.h" - -extern "C" void esp_schedule(); -extern "C" void esp_yield(); - -// ----------------------------------------------------------------------------------------------------------------------- -// ---------------------------------------------------- Private functions ------------------------------------------------ -// ----------------------------------------------------------------------------------------------------------------------- - - - - -// ----------------------------------------------------------------------------------------------------------------------- -// ----------------------------------------------------- scan function --------------------------------------------------- -// ----------------------------------------------------------------------------------------------------------------------- - -bool ESP8266WiFiScanClass::_scanAsync = false; -bool ESP8266WiFiScanClass::_scanStarted = false; -bool ESP8266WiFiScanClass::_scanComplete = false; - -size_t ESP8266WiFiScanClass::_scanCount = 0; -void* ESP8266WiFiScanClass::_scanResult = 0; - -std::function ESP8266WiFiScanClass::_onComplete; - -/** - * Start scan WiFi networks available - * @param async run in async mode - * @param show_hidden show hidden networks - * @param channel scan only this channel (0 for all channels) - * @param ssid* scan for only this ssid (NULL for all ssid's) - * @return Number of discovered networks - */ -int8_t ESP8266WiFiScanClass::scanNetworks(bool async, bool show_hidden, uint8 channel, uint8* ssid) { - if(ESP8266WiFiScanClass::_scanStarted) { - return WIFI_SCAN_RUNNING; - } - - ESP8266WiFiScanClass::_scanAsync = async; - - WiFi.enableSTA(true); - - int status = wifi_station_get_connect_status(); - if(status != STATION_GOT_IP && status != STATION_IDLE) { - wifi_station_disconnect(); - } - - scanDelete(); - - struct scan_config config; - memset(&config, 0, sizeof(config)); - config.ssid = ssid; - config.channel = channel; - config.show_hidden = show_hidden; - if(wifi_station_scan(&config, reinterpret_cast(&ESP8266WiFiScanClass::_scanDone))) { - ESP8266WiFiScanClass::_scanComplete = false; - ESP8266WiFiScanClass::_scanStarted = true; - - if(ESP8266WiFiScanClass::_scanAsync) { - delay(0); // time for the OS to trigger the scan - return WIFI_SCAN_RUNNING; - } - - esp_yield(); // will resume when _scanDone fires - return ESP8266WiFiScanClass::_scanCount; - } else { - return WIFI_SCAN_FAILED; - } - -} - -/** - * Starts scanning WiFi networks available in async mode - * @param onComplete the event handler executed when the scan is done - * @param show_hidden show hidden networks - */ -void ESP8266WiFiScanClass::scanNetworksAsync(std::function onComplete, bool show_hidden) { - _onComplete = onComplete; - scanNetworks(true, show_hidden); -} - -/** - * called to get the scan state in Async mode - * @return scan result or status - * -1 if scan not fin - * -2 if scan not triggered - */ -int8_t ESP8266WiFiScanClass::scanComplete() { - - if(_scanStarted) { - return WIFI_SCAN_RUNNING; - } - - if(_scanComplete) { - return ESP8266WiFiScanClass::_scanCount; - } - - return WIFI_SCAN_FAILED; -} - -/** - * delete last scan result from RAM - */ -void ESP8266WiFiScanClass::scanDelete() { - if(ESP8266WiFiScanClass::_scanResult) { - delete[] reinterpret_cast(ESP8266WiFiScanClass::_scanResult); - ESP8266WiFiScanClass::_scanResult = 0; - ESP8266WiFiScanClass::_scanCount = 0; - } - _scanComplete = false; -} - - -/** - * loads all infos from a scanned wifi in to the ptr parameters - * @param networkItem uint8_t - * @param ssid const char** - * @param encryptionType uint8_t * - * @param RSSI int32_t * - * @param BSSID uint8_t ** - * @param channel int32_t * - * @param isHidden bool * - * @return (true if ok) - */ -bool ESP8266WiFiScanClass::getNetworkInfo(uint8_t i, String &ssid, uint8_t &encType, int32_t &rssi, uint8_t* &bssid, int32_t &channel, bool &isHidden) { - struct bss_info* it = reinterpret_cast(_getScanInfoByIndex(i)); - if(!it) { - return false; - } - - char ssid_copy[33]; // Ensure space for maximum len SSID (32) plus trailing 0 - memcpy(ssid_copy, it->ssid, sizeof(it->ssid)); - ssid_copy[32] = 0; // Potentially add 0-termination if none present earlier - ssid = (const char*) ssid_copy; - encType = encryptionType(i); - rssi = it->rssi; - bssid = it->bssid; // move ptr - channel = it->channel; - isHidden = (it->is_hidden != 0); - - return true; -} - - -/** - * Return the SSID discovered during the network scan. - * @param i specify from which network item want to get the information - * @return ssid string of the specified item on the networks scanned list - */ -String ESP8266WiFiScanClass::SSID(uint8_t i) { - struct bss_info* it = reinterpret_cast(_getScanInfoByIndex(i)); - if(!it) { - return ""; - } - char tmp[33]; //ssid can be up to 32chars, => plus null term - memcpy(tmp, it->ssid, sizeof(it->ssid)); - tmp[32] = 0; //nullterm in case of 32 char ssid - - return String(reinterpret_cast(tmp)); -} - - -/** - * Return the encryption type of the networks discovered during the scanNetworks - * @param i specify from which network item want to get the information - * @return encryption type (enum wl_enc_type) of the specified item on the networks scanned list - */ -uint8_t ESP8266WiFiScanClass::encryptionType(uint8_t i) { - struct bss_info* it = reinterpret_cast(_getScanInfoByIndex(i)); - if(!it) { - return -1; - } - - switch(it->authmode) { - case AUTH_OPEN: - return ENC_TYPE_NONE; - case AUTH_WEP: - return ENC_TYPE_WEP; - case AUTH_WPA_PSK: - return ENC_TYPE_TKIP; - case AUTH_WPA2_PSK: - return ENC_TYPE_CCMP; - case AUTH_WPA_WPA2_PSK: - return ENC_TYPE_AUTO; - default: - return -1; - } -} - -/** - * Return the RSSI of the networks discovered during the scanNetworks - * @param i specify from which network item want to get the information - * @return signed value of RSSI of the specified item on the networks scanned list - */ -int32_t ESP8266WiFiScanClass::RSSI(uint8_t i) { - struct bss_info* it = reinterpret_cast(_getScanInfoByIndex(i)); - if(!it) { - return 0; - } - return it->rssi; -} - - -/** - * return MAC / BSSID of scanned wifi - * @param i specify from which network item want to get the information - * @return uint8_t * MAC / BSSID of scanned wifi - */ -uint8_t * ESP8266WiFiScanClass::BSSID(uint8_t i) { - struct bss_info* it = reinterpret_cast(_getScanInfoByIndex(i)); - if(!it) { - return 0; - } - return it->bssid; -} - -/** - * return MAC / BSSID of scanned wifi - * @param i specify from which network item want to get the information - * @return String MAC / BSSID of scanned wifi - */ -String ESP8266WiFiScanClass::BSSIDstr(uint8_t i) { - char mac[18] = { 0 }; - struct bss_info* it = reinterpret_cast(_getScanInfoByIndex(i)); - if(!it) { - return String(""); - } - sprintf(mac, "%02X:%02X:%02X:%02X:%02X:%02X", it->bssid[0], it->bssid[1], it->bssid[2], it->bssid[3], it->bssid[4], it->bssid[5]); - return String(mac); -} - -int32_t ESP8266WiFiScanClass::channel(uint8_t i) { - struct bss_info* it = reinterpret_cast(_getScanInfoByIndex(i)); - if(!it) { - return 0; - } - return it->channel; -} - -/** - * return if the scanned wifi is Hidden (no SSID) - * @param networkItem specify from which network item want to get the information - * @return bool (true == hidden) - */ -bool ESP8266WiFiScanClass::isHidden(uint8_t i) { - struct bss_info* it = reinterpret_cast(_getScanInfoByIndex(i)); - if(!it) { - return false; - } - return (it->is_hidden != 0); -} - -/** - * private - * scan callback - * @param result void *arg - * @param status STATUS - */ -void ESP8266WiFiScanClass::_scanDone(void* result, int status) { - if(status != OK) { - ESP8266WiFiScanClass::_scanCount = 0; - ESP8266WiFiScanClass::_scanResult = 0; - } else { - - int i = 0; - bss_info* head = reinterpret_cast(result); - - for(bss_info* it = head; it; it = STAILQ_NEXT(it, next), ++i) - ; - ESP8266WiFiScanClass::_scanCount = i; - if(i == 0) { - ESP8266WiFiScanClass::_scanResult = 0; - } else { - bss_info* copied_info = new bss_info[i]; - i = 0; - for(bss_info* it = head; it; it = STAILQ_NEXT(it, next), ++i) { - memcpy(copied_info + i, it, sizeof(bss_info)); - } - - ESP8266WiFiScanClass::_scanResult = copied_info; - } - - } - - ESP8266WiFiScanClass::_scanStarted = false; - ESP8266WiFiScanClass::_scanComplete = true; - - if(!ESP8266WiFiScanClass::_scanAsync) { - esp_schedule(); // resume scanNetworks - } else if (ESP8266WiFiScanClass::_onComplete) { - ESP8266WiFiScanClass::_onComplete(ESP8266WiFiScanClass::_scanCount); - ESP8266WiFiScanClass::_onComplete = nullptr; - } -} - -/** - * - * @param i specify from which network item want to get the information - * @return bss_info * - */ -void * ESP8266WiFiScanClass::_getScanInfoByIndex(int i) { - if(!ESP8266WiFiScanClass::_scanResult || (size_t) i > ESP8266WiFiScanClass::_scanCount) { - return 0; - } - return reinterpret_cast(ESP8266WiFiScanClass::_scanResult) + i; -} diff --git a/extras/ESP8266WiFi_nossl_noleak/src/ESP8266WiFiScan.h b/extras/ESP8266WiFi_nossl_noleak/src/ESP8266WiFiScan.h deleted file mode 100644 index 060a5a4..0000000 --- a/extras/ESP8266WiFi_nossl_noleak/src/ESP8266WiFiScan.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - ESP8266WiFiScan.h - esp8266 Wifi support. - Based on WiFi.h from Ardiono WiFi shield library. - Copyright (c) 2011-2014 Arduino. All right reserved. - Modified by Ivan Grokhotkov, December 2014 - Reworked by Markus Sattler, December 2015 - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef ESP8266WIFISCAN_H_ -#define ESP8266WIFISCAN_H_ - -#include "ESP8266WiFiType.h" -#include "ESP8266WiFiGeneric.h" - -class ESP8266WiFiScanClass { - - // ---------------------------------------------------------------------------------------------- - // ----------------------------------------- scan function -------------------------------------- - // ---------------------------------------------------------------------------------------------- - - public: - - int8_t scanNetworks(bool async = false, bool show_hidden = false, uint8 channel = 0, uint8* ssid = NULL); - void scanNetworksAsync(std::function onComplete, bool show_hidden = false); - - int8_t scanComplete(); - void scanDelete(); - - // scan result - bool getNetworkInfo(uint8_t networkItem, String &ssid, uint8_t &encryptionType, int32_t &RSSI, uint8_t* &BSSID, int32_t &channel, bool &isHidden); - - String SSID(uint8_t networkItem); - uint8_t encryptionType(uint8_t networkItem); - int32_t RSSI(uint8_t networkItem); - uint8_t * BSSID(uint8_t networkItem); - String BSSIDstr(uint8_t networkItem); - int32_t channel(uint8_t networkItem); - bool isHidden(uint8_t networkItem); - - protected: - - static bool _scanAsync; - static bool _scanStarted; - static bool _scanComplete; - - static size_t _scanCount; - static void* _scanResult; - - static std::function _onComplete; - - static void _scanDone(void* result, int status); - static void * _getScanInfoByIndex(int i); - -}; - - -#endif /* ESP8266WIFISCAN_H_ */ diff --git a/extras/ESP8266WiFi_nossl_noleak/src/ESP8266WiFiType.h b/extras/ESP8266WiFi_nossl_noleak/src/ESP8266WiFiType.h deleted file mode 100644 index 2b0348a..0000000 --- a/extras/ESP8266WiFi_nossl_noleak/src/ESP8266WiFiType.h +++ /dev/null @@ -1,153 +0,0 @@ -/* - ESP8266WiFiType.h - esp8266 Wifi support. - Copyright (c) 2011-2014 Arduino. All right reserved. - Modified by Ivan Grokhotkov, December 2014 - Reworked by Markus Sattler, December 2015 - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - - -#ifndef ESP8266WIFITYPE_H_ -#define ESP8266WIFITYPE_H_ - -#include - -#define WIFI_SCAN_RUNNING (-1) -#define WIFI_SCAN_FAILED (-2) - -// Note: these enums need to be in sync with the SDK! - -// TODO: replace/deprecate/remove enum typedefs ending with _t below - -typedef enum WiFiMode -{ - WIFI_OFF = 0, WIFI_STA = 1, WIFI_AP = 2, WIFI_AP_STA = 3, - /* these two pseudo modes are experimental: */ WIFI_SHUTDOWN = 4, WIFI_RESUME = 8 -} WiFiMode_t; - -typedef enum WiFiPhyMode -{ - WIFI_PHY_MODE_11B = 1, WIFI_PHY_MODE_11G = 2, WIFI_PHY_MODE_11N = 3 -} WiFiPhyMode_t; - -typedef enum WiFiSleepType -{ - WIFI_NONE_SLEEP = 0, WIFI_LIGHT_SLEEP = 1, WIFI_MODEM_SLEEP = 2 -} WiFiSleepType_t; - - -typedef enum WiFiEvent -{ - WIFI_EVENT_STAMODE_CONNECTED = 0, - WIFI_EVENT_STAMODE_DISCONNECTED, - WIFI_EVENT_STAMODE_AUTHMODE_CHANGE, - WIFI_EVENT_STAMODE_GOT_IP, - WIFI_EVENT_STAMODE_DHCP_TIMEOUT, - WIFI_EVENT_SOFTAPMODE_STACONNECTED, - WIFI_EVENT_SOFTAPMODE_STADISCONNECTED, - WIFI_EVENT_SOFTAPMODE_PROBEREQRECVED, - WIFI_EVENT_MODE_CHANGE, - WIFI_EVENT_SOFTAPMODE_DISTRIBUTE_STA_IP, - WIFI_EVENT_MAX, - WIFI_EVENT_ANY = WIFI_EVENT_MAX, -} WiFiEvent_t; - -enum WiFiDisconnectReason -{ - WIFI_DISCONNECT_REASON_UNSPECIFIED = 1, - WIFI_DISCONNECT_REASON_AUTH_EXPIRE = 2, - WIFI_DISCONNECT_REASON_AUTH_LEAVE = 3, - WIFI_DISCONNECT_REASON_ASSOC_EXPIRE = 4, - WIFI_DISCONNECT_REASON_ASSOC_TOOMANY = 5, - WIFI_DISCONNECT_REASON_NOT_AUTHED = 6, - WIFI_DISCONNECT_REASON_NOT_ASSOCED = 7, - WIFI_DISCONNECT_REASON_ASSOC_LEAVE = 8, - WIFI_DISCONNECT_REASON_ASSOC_NOT_AUTHED = 9, - WIFI_DISCONNECT_REASON_DISASSOC_PWRCAP_BAD = 10, /* 11h */ - WIFI_DISCONNECT_REASON_DISASSOC_SUPCHAN_BAD = 11, /* 11h */ - WIFI_DISCONNECT_REASON_IE_INVALID = 13, /* 11i */ - WIFI_DISCONNECT_REASON_MIC_FAILURE = 14, /* 11i */ - WIFI_DISCONNECT_REASON_4WAY_HANDSHAKE_TIMEOUT = 15, /* 11i */ - WIFI_DISCONNECT_REASON_GROUP_KEY_UPDATE_TIMEOUT = 16, /* 11i */ - WIFI_DISCONNECT_REASON_IE_IN_4WAY_DIFFERS = 17, /* 11i */ - WIFI_DISCONNECT_REASON_GROUP_CIPHER_INVALID = 18, /* 11i */ - WIFI_DISCONNECT_REASON_PAIRWISE_CIPHER_INVALID = 19, /* 11i */ - WIFI_DISCONNECT_REASON_AKMP_INVALID = 20, /* 11i */ - WIFI_DISCONNECT_REASON_UNSUPP_RSN_IE_VERSION = 21, /* 11i */ - WIFI_DISCONNECT_REASON_INVALID_RSN_IE_CAP = 22, /* 11i */ - WIFI_DISCONNECT_REASON_802_1X_AUTH_FAILED = 23, /* 11i */ - WIFI_DISCONNECT_REASON_CIPHER_SUITE_REJECTED = 24, /* 11i */ - - WIFI_DISCONNECT_REASON_BEACON_TIMEOUT = 200, - WIFI_DISCONNECT_REASON_NO_AP_FOUND = 201, - WIFI_DISCONNECT_REASON_AUTH_FAIL = 202, - WIFI_DISCONNECT_REASON_ASSOC_FAIL = 203, - WIFI_DISCONNECT_REASON_HANDSHAKE_TIMEOUT = 204, -}; - -struct WiFiEventModeChange -{ - WiFiMode oldMode; - WiFiMode newMode; -}; - -struct WiFiEventStationModeConnected -{ - String ssid; - uint8 bssid[6]; - uint8 channel; -}; - -struct WiFiEventStationModeDisconnected -{ - String ssid; - uint8 bssid[6]; - WiFiDisconnectReason reason; -}; - -struct WiFiEventStationModeAuthModeChanged -{ - uint8 oldMode; - uint8 newMode; -}; - -struct WiFiEventStationModeGotIP -{ - IPAddress ip; - IPAddress mask; - IPAddress gw; -}; - -struct WiFiEventSoftAPModeStationConnected -{ - uint8 mac[6]; - uint8 aid; -}; - -struct WiFiEventSoftAPModeStationDisconnected -{ - uint8 mac[6]; - uint8 aid; -}; - -struct WiFiEventSoftAPModeProbeRequestReceived -{ - int rssi; - uint8 mac[6]; -}; - - -#endif /* ESP8266WIFITYPE_H_ */ diff --git a/extras/ESP8266WiFi_nossl_noleak/src/WiFiClient.cpp b/extras/ESP8266WiFi_nossl_noleak/src/WiFiClient.cpp deleted file mode 100644 index 2d7b5ac..0000000 --- a/extras/ESP8266WiFi_nossl_noleak/src/WiFiClient.cpp +++ /dev/null @@ -1,425 +0,0 @@ -/* - WiFiClient.cpp - TCP/IP client for esp8266, mostly compatible - with Arduino WiFi shield library - - Copyright (c) 2014 Ivan Grokhotkov. All rights reserved. - This file is part of the esp8266 core for Arduino environment. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#define LWIP_INTERNAL - -extern "C" -{ - #include "include/wl_definitions.h" - #include "osapi.h" - #include "ets_sys.h" -} - -#include "debug.h" -#include "ESP8266WiFi.h" -#include "WiFiClient.h" -#include "WiFiServer.h" -#include "lwip/opt.h" -#include "lwip/ip.h" -#include "lwip/tcp.h" -#include "lwip/inet.h" -#include "lwip/netif.h" -#include -#include "c_types.h" - -uint16_t WiFiClient::_localPort = 0; - -static bool defaultNoDelay = false; // false == Nagle enabled by default -static bool defaultSync = false; - -bool getDefaultPrivateGlobalSyncValue () -{ - return defaultSync; -} - -void WiFiClient::setDefaultNoDelay (bool noDelay) -{ - defaultNoDelay = noDelay; -} - -void WiFiClient::setDefaultSync (bool sync) -{ - defaultSync = sync; -} - -bool WiFiClient::getDefaultNoDelay () -{ - return defaultNoDelay; -} - -bool WiFiClient::getDefaultSync () -{ - return defaultSync; -} - -template<> -WiFiClient* SList::_s_first = 0; - - -WiFiClient::WiFiClient() -: _client(0) -{ - _timeout = 5000; - WiFiClient::_add(this); -} - -WiFiClient::WiFiClient(ClientContext* client) -: _client(client) -{ - _timeout = 5000; - _client->ref(); - WiFiClient::_add(this); - - setSync(defaultSync); - setNoDelay(defaultNoDelay); -} - -WiFiClient::~WiFiClient() -{ - WiFiClient::_remove(this); - if (_client) - _client->unref(); -} - -WiFiClient::WiFiClient(const WiFiClient& other) -{ - _client = other._client; - _timeout = other._timeout; - _localPort = other._localPort; - if (_client) - _client->ref(); - WiFiClient::_add(this); -} - -WiFiClient& WiFiClient::operator=(const WiFiClient& other) -{ - if (_client) - _client->unref(); - _client = other._client; - _timeout = other._timeout; - _localPort = other._localPort; - if (_client) - _client->ref(); - return *this; -} - -int WiFiClient::connect(const char* host, uint16_t port) -{ - IPAddress remote_addr; - if (WiFi.hostByName(host, remote_addr, _timeout)) - { - return connect(remote_addr, port); - } - return 0; -} - -int WiFiClient::connect(const String& host, uint16_t port) -{ - return connect(host.c_str(), port); -} - -int WiFiClient::connect(IPAddress ip, uint16_t port) -{ - if (_client) { - stop(); - _client->unref(); - _client = nullptr; - } - -#if LWIP_VERSION_MAJOR == 1 - // if the default interface is down, tcp_connect exits early without - // ever calling tcp_err - // http://lists.gnu.org/archive/html/lwip-devel/2010-05/msg00001.html - netif* interface = ip_route(ip); - if (!interface) { - DEBUGV("no route to host\r\n"); - return 0; - } -#endif - - tcp_pcb* pcb = tcp_new(); - if (!pcb) - return 0; - - if (_localPort > 0) { - pcb->local_port = _localPort++; - } - - _client = new ClientContext(pcb, nullptr, nullptr); - _client->ref(); - _client->setTimeout(_timeout); - int res = _client->connect(ip, port); - if (res == 0) { - _client->unref(); - _client = nullptr; - return 0; - } - - setSync(defaultSync); - setNoDelay(defaultNoDelay); - - return 1; -} - -void WiFiClient::setNoDelay(bool nodelay) { - if (!_client) - return; - _client->setNoDelay(nodelay); -} - -bool WiFiClient::getNoDelay() const { - if (!_client) - return false; - return _client->getNoDelay(); -} - -void WiFiClient::setSync(bool sync) -{ - if (!_client) - return; - _client->setSync(sync); -} - -bool WiFiClient::getSync() const -{ - if (!_client) - return false; - return _client->getSync(); -} - -size_t WiFiClient::availableForWrite () -{ - return _client? _client->availableForWrite(): 0; -} - -size_t WiFiClient::write(uint8_t b) -{ - return write(&b, 1); -} - -size_t WiFiClient::write(const uint8_t *buf, size_t size) -{ - if (!_client || !size) - { - return 0; - } - _client->setTimeout(_timeout); - return _client->write(buf, size); -} - -size_t WiFiClient::write(Stream& stream, size_t unused) -{ - (void) unused; - return WiFiClient::write(stream); -} - -size_t WiFiClient::write(Stream& stream) -{ - if (!_client || !stream.available()) - { - return 0; - } - _client->setTimeout(_timeout); - return _client->write(stream); -} - -size_t WiFiClient::write_P(PGM_P buf, size_t size) -{ - if (!_client || !size) - { - return 0; - } - _client->setTimeout(_timeout); - return _client->write_P(buf, size); -} - -int WiFiClient::available() -{ - if (!_client) - return false; - - int result = _client->getSize(); - - if (!result) { - optimistic_yield(100); - } - return result; -} - -int WiFiClient::read() -{ - if (!available()) - return -1; - - return _client->read(); -} - - -int WiFiClient::read(uint8_t* buf, size_t size) -{ - return (int) _client->read(reinterpret_cast(buf), size); -} - -int WiFiClient::peek() -{ - if (!available()) - return -1; - - return _client->peek(); -} - -size_t WiFiClient::peekBytes(uint8_t *buffer, size_t length) { - size_t count = 0; - - if(!_client) { - return 0; - } - - _startMillis = millis(); - while((available() < (int) length) && ((millis() - _startMillis) < _timeout)) { - yield(); - } - - if(available() < (int) length) { - count = available(); - } else { - count = length; - } - - return _client->peekBytes((char *)buffer, count); -} - -bool WiFiClient::flush(unsigned int maxWaitMs) -{ - if (!_client) - return true; - - if (maxWaitMs == 0) - maxWaitMs = WIFICLIENT_MAX_FLUSH_WAIT_MS; - return _client->wait_until_sent(maxWaitMs); -} - -bool WiFiClient::stop(unsigned int maxWaitMs) -{ - if (!_client) - return true; - - bool ret = flush(maxWaitMs); // virtual, may be ssl's - if (_client->close() != ERR_OK) - ret = false; - return ret; -} - -uint8_t WiFiClient::connected() -{ - if (!_client || _client->state() == CLOSED) - return 0; - - return _client->state() == ESTABLISHED || available(); -} - -uint8_t WiFiClient::status() -{ - if (!_client) - return CLOSED; - return _client->state(); -} - -WiFiClient::operator bool() -{ - return connected(); -} - -IPAddress WiFiClient::remoteIP() -{ - if (!_client || !_client->getRemoteAddress()) - return IPAddress(0U); - - return _client->getRemoteAddress(); -} - -uint16_t WiFiClient::remotePort() -{ - if (!_client) - return 0; - - return _client->getRemotePort(); -} - -IPAddress WiFiClient::localIP() -{ - if (!_client) - return IPAddress(0U); - - return IPAddress(_client->getLocalAddress()); -} - -uint16_t WiFiClient::localPort() -{ - if (!_client) - return 0; - - return _client->getLocalPort(); -} - -void WiFiClient::stopAll() -{ - for (WiFiClient* it = _s_first; it; it = it->_next) { - it->stop(); - } -} - - -void WiFiClient::stopAllExcept(WiFiClient* except) -{ - for (WiFiClient* it = _s_first; it; it = it->_next) { - if (it != except) { - it->stop(); - } - } -} - - -void WiFiClient::keepAlive (uint16_t idle_sec, uint16_t intv_sec, uint8_t count) -{ - _client->keepAlive(idle_sec, intv_sec, count); -} - -bool WiFiClient::isKeepAliveEnabled () const -{ - return _client->isKeepAliveEnabled(); -} - -uint16_t WiFiClient::getKeepAliveIdle () const -{ - return _client->getKeepAliveIdle(); -} - -uint16_t WiFiClient::getKeepAliveInterval () const -{ - return _client->getKeepAliveInterval(); -} - -uint8_t WiFiClient::getKeepAliveCount () const -{ - return _client->getKeepAliveCount(); -} diff --git a/extras/ESP8266WiFi_nossl_noleak/src/WiFiClient.h b/extras/ESP8266WiFi_nossl_noleak/src/WiFiClient.h deleted file mode 100644 index 31f6d10..0000000 --- a/extras/ESP8266WiFi_nossl_noleak/src/WiFiClient.h +++ /dev/null @@ -1,135 +0,0 @@ -/* - WiFiClient.h - Library for Arduino Wifi shield. - Copyright (c) 2011-2014 Arduino. All right reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - Modified by Ivan Grokhotkov, December 2014 - esp8266 support -*/ - -#ifndef wificlient_h -#define wificlient_h -#include -#include "Arduino.h" -#include "Print.h" -#include "Client.h" -#include "IPAddress.h" -#include "include/slist.h" - -#ifndef TCP_MSS -#define TCP_MSS 1460 // lwip1.4 -#endif - -#define WIFICLIENT_MAX_PACKET_SIZE TCP_MSS -#define WIFICLIENT_MAX_FLUSH_WAIT_MS 300 - -#define TCP_DEFAULT_KEEPALIVE_IDLE_SEC 7200 // 2 hours -#define TCP_DEFAULT_KEEPALIVE_INTERVAL_SEC 75 // 75 sec -#define TCP_DEFAULT_KEEPALIVE_COUNT 9 // fault after 9 failures - -class ClientContext; -class WiFiServer; - -class WiFiClient : public Client, public SList { -protected: - WiFiClient(ClientContext* client); - -public: - WiFiClient(); - virtual ~WiFiClient(); - WiFiClient(const WiFiClient&); - WiFiClient& operator=(const WiFiClient&); - - uint8_t status(); - virtual int connect(IPAddress ip, uint16_t port) override; - virtual int connect(const char *host, uint16_t port) override; - virtual int connect(const String& host, uint16_t port); - virtual size_t write(uint8_t) override; - virtual size_t write(const uint8_t *buf, size_t size) override; - virtual size_t write_P(PGM_P buf, size_t size); - size_t write(Stream& stream); - - // This one is deprecated, use write(Stream& instead) - size_t write(Stream& stream, size_t unitSize) __attribute__ ((deprecated)); - - virtual int available() override; - virtual int read() override; - virtual int read(uint8_t *buf, size_t size) override; - virtual int peek() override; - virtual size_t peekBytes(uint8_t *buffer, size_t length); - size_t peekBytes(char *buffer, size_t length) { - return peekBytes((uint8_t *) buffer, length); - } - virtual void flush() override { (void)flush(0); } - virtual void stop() override { (void)stop(0); } - bool flush(unsigned int maxWaitMs); - bool stop(unsigned int maxWaitMs); - virtual uint8_t connected() override; - virtual operator bool() override; - - IPAddress remoteIP(); - uint16_t remotePort(); - IPAddress localIP(); - uint16_t localPort(); - - static void setLocalPortStart(uint16_t port) { _localPort = port; } - - size_t availableForWrite(); - - friend class WiFiServer; - - using Print::write; - - static void stopAll(); - static void stopAllExcept(WiFiClient * c); - - void keepAlive (uint16_t idle_sec = TCP_DEFAULT_KEEPALIVE_IDLE_SEC, uint16_t intv_sec = TCP_DEFAULT_KEEPALIVE_INTERVAL_SEC, uint8_t count = TCP_DEFAULT_KEEPALIVE_COUNT); - bool isKeepAliveEnabled () const; - uint16_t getKeepAliveIdle () const; - uint16_t getKeepAliveInterval () const; - uint8_t getKeepAliveCount () const; - void disableKeepAlive () { keepAlive(0, 0, 0); } - - // default NoDelay=False (Nagle=True=!NoDelay) - // Nagle is for shortly delaying outgoing data, to send less/bigger packets - // Nagle should be disabled for telnet-like/interactive streams - // Nagle is meaningless/ignored when Sync=true - static void setDefaultNoDelay (bool noDelay); - static bool getDefaultNoDelay (); - bool getNoDelay() const; - void setNoDelay(bool nodelay); - - // default Sync=false - // When sync is true, all writes are automatically flushed. - // This is slower but also does not allocate - // temporary memory for sending data - static void setDefaultSync (bool sync); - static bool getDefaultSync (); - bool getSync() const; - void setSync(bool sync); - -protected: - - static int8_t _s_connected(void* arg, void* tpcb, int8_t err); - static void _s_err(void* arg, int8_t err); - - int8_t _connected(void* tpcb, int8_t err); - void _err(int8_t err); - - ClientContext* _client; - static uint16_t _localPort; -}; - -#endif diff --git a/extras/ESP8266WiFi_nossl_noleak/src/WiFiServer.cpp b/extras/ESP8266WiFi_nossl_noleak/src/WiFiServer.cpp deleted file mode 100644 index d9d4765..0000000 --- a/extras/ESP8266WiFi_nossl_noleak/src/WiFiServer.cpp +++ /dev/null @@ -1,185 +0,0 @@ -/* - WiFiServer.cpp - TCP/IP server for esp8266, mostly compatible - with Arduino WiFi shield library - - Copyright (c) 2014 Ivan Grokhotkov. All rights reserved. - This file is part of the esp8266 core for Arduino environment. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - - -#define LWIP_INTERNAL - -extern "C" { - #include "osapi.h" - #include "ets_sys.h" -} - -#include "debug.h" -#include "ESP8266WiFi.h" -#include "WiFiClient.h" -#include "WiFiServer.h" -#include "lwip/opt.h" -#include "lwip/tcp.h" -#include "lwip/inet.h" -#include - -WiFiServer::WiFiServer(const IPAddress& addr, uint16_t port) -: _port(port) -, _addr(addr) -, _pcb(nullptr) -, _unclaimed(nullptr) -, _discarded(nullptr) -{ -} - -WiFiServer::WiFiServer(uint16_t port) -: _port(port) -, _addr(IP_ANY_TYPE) -, _pcb(nullptr) -, _unclaimed(nullptr) -, _discarded(nullptr) -{ -} - -void WiFiServer::begin() { - begin(_port); -} - -void WiFiServer::begin(uint16_t port) { - close(); - _port = port; - err_t err; - tcp_pcb* pcb = tcp_new(); - if (!pcb) - return; - - pcb->so_options |= SOF_REUSEADDR; - - // (IPAddress _addr) operator-converted to (const ip_addr_t*) - err = tcp_bind(pcb, _addr, _port); - - if (err != ERR_OK) { - tcp_close(pcb); - return; - } - - tcp_pcb* listen_pcb = tcp_listen(pcb); - if (!listen_pcb) { - tcp_close(pcb); - return; - } - _pcb = listen_pcb; - tcp_accept(listen_pcb, &WiFiServer::_s_accept); - tcp_arg(listen_pcb, (void*) this); -} - -void WiFiServer::setNoDelay(bool nodelay) { - _noDelay = nodelay? _ndTrue: _ndFalse; -} - -bool WiFiServer::getNoDelay() { - switch (_noDelay) - { - case _ndFalse: return false; - case _ndTrue: return true; - default: return WiFiClient::getDefaultNoDelay(); - } -} - -bool WiFiServer::hasClient() { - if (_unclaimed) - return true; - return false; -} - -WiFiClient WiFiServer::available(byte* status) { - (void) status; - if (_unclaimed) { - WiFiClient result(_unclaimed); - _unclaimed = _unclaimed->next(); - result.setNoDelay(getNoDelay()); - DEBUGV("WS:av\r\n"); - return result; - } - - optimistic_yield(1000); - return WiFiClient(); -} - -uint8_t WiFiServer::status() { - if (!_pcb) - return CLOSED; - return _pcb->state; -} - -void WiFiServer::close() { - if (!_pcb) { - return; - } - tcp_close(_pcb); - _pcb = nullptr; -} - -void WiFiServer::stop() { - close(); -} - -size_t WiFiServer::write(uint8_t b) { - return write(&b, 1); -} - -size_t WiFiServer::write(const uint8_t *buffer, size_t size) { - // write to all clients - // not implemented - (void) buffer; - (void) size; - return 0; -} - -template -T* slist_append_tail(T* head, T* item) { - if (!head) - return item; - T* last = head; - while(last->next()) - last = last->next(); - last->next(item); - return head; -} - -long WiFiServer::_accept(tcp_pcb* apcb, long err) { - (void) err; - DEBUGV("WS:ac\r\n"); - ClientContext* client = new ClientContext(apcb, &WiFiServer::_s_discard, this); - _unclaimed = slist_append_tail(_unclaimed, client); - tcp_accepted(_pcb); - return ERR_OK; -} - -void WiFiServer::_discard(ClientContext* client) { - (void) client; - // _discarded = slist_append_tail(_discarded, client); - DEBUGV("WS:dis\r\n"); -} - -long WiFiServer::_s_accept(void *arg, tcp_pcb* newpcb, long err) { - return reinterpret_cast(arg)->_accept(newpcb, err); -} - -void WiFiServer::_s_discard(void* server, ClientContext* ctx) { - reinterpret_cast(server)->_discard(ctx); -} diff --git a/extras/ESP8266WiFi_nossl_noleak/src/WiFiServer.h b/extras/ESP8266WiFi_nossl_noleak/src/WiFiServer.h deleted file mode 100644 index ec0cea1..0000000 --- a/extras/ESP8266WiFi_nossl_noleak/src/WiFiServer.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - WiFiServer.h - Library for Arduino Wifi shield. - Copyright (c) 2011-2014 Arduino LLC. All right reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - Modified by Ivan Grokhotkov, December 2014 - esp8266 support -*/ - -#ifndef wifiserver_h -#define wifiserver_h - -extern "C" { - #include "include/wl_definitions.h" - - struct tcp_pcb; -} - -#include "Server.h" -#include "IPAddress.h" - -class ClientContext; -class WiFiClient; - -class WiFiServer : public Server { - // Secure server needs access to all the private entries here -protected: - uint16_t _port; - IPAddress _addr; - tcp_pcb* _pcb; - - ClientContext* _unclaimed; - ClientContext* _discarded; - enum { _ndDefault, _ndFalse, _ndTrue } _noDelay = _ndDefault; - -public: - WiFiServer(const IPAddress& addr, uint16_t port); - WiFiServer(uint16_t port); - virtual ~WiFiServer() {} - WiFiClient available(uint8_t* status = NULL); - bool hasClient(); - void begin(); - void begin(uint16_t port); - void setNoDelay(bool nodelay); - bool getNoDelay(); - virtual size_t write(uint8_t); - virtual size_t write(const uint8_t *buf, size_t size); - uint8_t status(); - void close(); - void stop(); - - using Print::write; - using ClientType = WiFiClient; - -protected: - long _accept(tcp_pcb* newpcb, long err); - void _discard(ClientContext* client); - - static long _s_accept(void *arg, tcp_pcb* newpcb, long err); - static void _s_discard(void* server, ClientContext* ctx); -}; - -#endif diff --git a/extras/ESP8266WiFi_nossl_noleak/src/WiFiUdp.cpp b/extras/ESP8266WiFi_nossl_noleak/src/WiFiUdp.cpp deleted file mode 100644 index a0a5c1d..0000000 --- a/extras/ESP8266WiFi_nossl_noleak/src/WiFiUdp.cpp +++ /dev/null @@ -1,281 +0,0 @@ -/* - WiFiUdp.cpp - UDP client/server for esp8266, mostly compatible - with Arduino WiFi shield library - - Copyright (c) 2015 Ivan Grokhotkov. All rights reserved. - This file is part of the esp8266 core for Arduino environment. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#define LWIP_INTERNAL -#include - -extern "C" -{ - #include "include/wl_definitions.h" - #include "osapi.h" - #include "ets_sys.h" -} - -#include "debug.h" -#include "ESP8266WiFi.h" -#include "WiFiUdp.h" -#include "lwip/opt.h" -#include "lwip/udp.h" -#include "lwip/inet.h" -#include "lwip/igmp.h" -#include "lwip/mem.h" -#include - -template<> -WiFiUDP* SList::_s_first = 0; - -/* Constructor */ -WiFiUDP::WiFiUDP() : _ctx(0) -{ - WiFiUDP::_add(this); -} - -WiFiUDP::WiFiUDP(const WiFiUDP& other) -{ - _ctx = other._ctx; - if (_ctx) - _ctx->ref(); - WiFiUDP::_add(this); -} - -WiFiUDP& WiFiUDP::operator=(const WiFiUDP& rhs) -{ - _ctx = rhs._ctx; - if (_ctx) - _ctx->ref(); - return *this; -} - -WiFiUDP::~WiFiUDP() -{ - WiFiUDP::_remove(this); - if (_ctx) - _ctx->unref(); -} - -/* Start WiFiUDP socket, listening at local port */ -uint8_t WiFiUDP::begin(uint16_t port) -{ - if (_ctx) { - _ctx->unref(); - _ctx = 0; - } - - _ctx = new UdpContext; - _ctx->ref(); - return (_ctx->listen(IPAddress(), port)) ? 1 : 0; -} - -uint8_t WiFiUDP::beginMulticast(IPAddress interfaceAddr, IPAddress multicast, uint16_t port) -{ - if (_ctx) { - _ctx->unref(); - _ctx = 0; - } - - if (igmp_joingroup(interfaceAddr, multicast)!= ERR_OK) { - return 0; - } - - _ctx = new UdpContext; - _ctx->ref(); - ip_addr_t addr = IPADDR4_INIT(INADDR_ANY); - if (!_ctx->listen(&addr, port)) { - return 0; - } - - return 1; -} - -/* return number of bytes available in the current packet, - will return zero if parsePacket hasn't been called yet */ -int WiFiUDP::available() { - int result = 0; - - if (_ctx) { - result = static_cast(_ctx->getSize()); - } - - if (!result) { - // yielding here will not make more data "available", - // but it will prevent the system from going into WDT reset - optimistic_yield(1000); - } - - return result; -} - -/* Release any resources being used by this WiFiUDP instance */ -void WiFiUDP::stop() -{ - if (_ctx) { - _ctx->disconnect(); - _ctx->unref(); - } - _ctx = 0; -} - -int WiFiUDP::beginPacket(const char *host, uint16_t port) -{ - IPAddress remote_addr; - if (WiFi.hostByName(host, remote_addr)) - { - return beginPacket(remote_addr, port); - } - return 0; -} - -int WiFiUDP::beginPacket(IPAddress ip, uint16_t port) -{ - if (!_ctx) { - _ctx = new UdpContext; - _ctx->ref(); - } - return (_ctx->connect(ip, port)) ? 1 : 0; -} - -int WiFiUDP::beginPacketMulticast(IPAddress multicastAddress, uint16_t port, - IPAddress interfaceAddress, int ttl) -{ - if (!_ctx) { - _ctx = new UdpContext; - _ctx->ref(); - } - if (!_ctx->connect(multicastAddress, port)) { - return 0; - } - _ctx->setMulticastInterface(interfaceAddress); - _ctx->setMulticastTTL(ttl); - return 1; -} - -int WiFiUDP::endPacket() -{ - if (!_ctx) - return 0; - - return (_ctx->send()) ? 1 : 0; -} - -size_t WiFiUDP::write(uint8_t byte) -{ - return write(&byte, 1); -} - -size_t WiFiUDP::write(const uint8_t *buffer, size_t size) -{ - if (!_ctx) - return 0; - - return _ctx->append(reinterpret_cast(buffer), size); -} - -int WiFiUDP::parsePacket() -{ - if (!_ctx) - return 0; - - if (!_ctx->next()) { - optimistic_yield(100); - return 0; - } - - return _ctx->getSize(); -} - -int WiFiUDP::read() -{ - if (!_ctx) - return -1; - - return _ctx->read(); -} - -int WiFiUDP::read(unsigned char* buffer, size_t len) -{ - if (!_ctx) - return 0; - - return _ctx->read(reinterpret_cast(buffer), len); -} - -int WiFiUDP::peek() -{ - if (!_ctx) - return -1; - - return _ctx->peek(); -} - -void WiFiUDP::flush() -{ - endPacket(); -} - -IPAddress WiFiUDP::remoteIP() -{ - if (!_ctx) - return INADDR_ANY; - - return _ctx->getRemoteAddress(); -} - -uint16_t WiFiUDP::remotePort() -{ - if (!_ctx) - return 0; - - return _ctx->getRemotePort(); -} - -IPAddress WiFiUDP::destinationIP() const -{ - if (!_ctx) - return INADDR_ANY; - - return _ctx->getDestAddress(); -} - -uint16_t WiFiUDP::localPort() const -{ - if (!_ctx) - return 0; - - return _ctx->getLocalPort(); -} - -void WiFiUDP::stopAll() -{ - for (WiFiUDP* it = _s_first; it; it = it->_next) { - DEBUGV("%s %p %p\n", __func__, it, _s_first); - it->stop(); - } -} - -void WiFiUDP::stopAllExcept(WiFiUDP * exC) { - for (WiFiUDP* it = _s_first; it; it = it->_next) { - if (it->_ctx != exC->_ctx) { - DEBUGV("%s %p %p\n", __func__, it, _s_first); - it->stop(); - } - } -} diff --git a/extras/ESP8266WiFi_nossl_noleak/src/WiFiUdp.h b/extras/ESP8266WiFi_nossl_noleak/src/WiFiUdp.h deleted file mode 100644 index a1cf42b..0000000 --- a/extras/ESP8266WiFi_nossl_noleak/src/WiFiUdp.h +++ /dev/null @@ -1,113 +0,0 @@ -/* - WiFiUdp.h - Library for Arduino Wifi shield. - Copyright (c) 2011-2014 Arduino LLC. All right reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - - Modified by Ivan Grokhotkov, January 2015 - esp8266 support -*/ - -#ifndef WIFIUDP_H -#define WIFIUDP_H - -#include -#include - -#define UDP_TX_PACKET_MAX_SIZE 8192 - -class UdpContext; - -class WiFiUDP : public UDP, public SList { -private: - UdpContext* _ctx; - -public: - WiFiUDP(); // Constructor - WiFiUDP(const WiFiUDP& other); - WiFiUDP& operator=(const WiFiUDP& rhs); - virtual ~WiFiUDP(); - - operator bool() const { return _ctx != 0; } - - // initialize, start listening on specified port. - // Returns 1 if successful, 0 if there are no sockets available to use - uint8_t begin(uint16_t port) override; - // Finish with the UDP connetion - void stop() override; - // join a multicast group and listen on the given port - uint8_t beginMulticast(IPAddress interfaceAddr, IPAddress multicast, uint16_t port); - - // Sending UDP packets - - // Start building up a packet to send to the remote host specific in ip and port - // Returns 1 if successful, 0 if there was a problem with the supplied IP address or port - int beginPacket(IPAddress ip, uint16_t port) override; - // Start building up a packet to send to the remote host specific in host and port - // Returns 1 if successful, 0 if there was a problem resolving the hostname or port - int beginPacket(const char *host, uint16_t port) override; - // Start building up a packet to send to the multicast address - // multicastAddress - muticast address to send to - // interfaceAddress - the local IP address of the interface that should be used - // use WiFi.localIP() or WiFi.softAPIP() depending on the interface you need - // ttl - multicast packet TTL (default is 1) - // Returns 1 if successful, 0 if there was a problem with the supplied IP address or port - virtual int beginPacketMulticast(IPAddress multicastAddress, - uint16_t port, - IPAddress interfaceAddress, - int ttl = 1); - // Finish off this packet and send it - // Returns 1 if the packet was sent successfully, 0 if there was an error - int endPacket() override; - // Write a single byte into the packet - size_t write(uint8_t) override; - // Write size bytes from buffer into the packet - size_t write(const uint8_t *buffer, size_t size) override; - - using Print::write; - - // Start processing the next available incoming packet - // Returns the size of the packet in bytes, or 0 if no packets are available - int parsePacket() override; - // Number of bytes remaining in the current packet - int available() override; - // Read a single byte from the current packet - int read() override; - // Read up to len bytes from the current packet and place them into buffer - // Returns the number of bytes read, or 0 if none are available - int read(unsigned char* buffer, size_t len) override; - // Read up to len characters from the current packet and place them into buffer - // Returns the number of characters read, or 0 if none are available - int read(char* buffer, size_t len) override { return read((unsigned char*)buffer, len); }; - // Return the next byte from the current packet without moving on to the next byte - int peek() override; - void flush() override; // Finish reading the current packet - - // Return the IP address of the host who sent the current incoming packet - IPAddress remoteIP() override; - // Return the port of the host who sent the current incoming packet - uint16_t remotePort() override; - // Return the destination address for incoming packets, - // useful to distinguish multicast and ordinary packets - IPAddress destinationIP() const; - // Return the local port for outgoing packets - uint16_t localPort() const; - - static void stopAll(); - static void stopAllExcept(WiFiUDP * exC); - -}; - -#endif //WIFIUDP_H - diff --git a/extras/ESP8266WiFi_nossl_noleak/src/include/ClientContext.h b/extras/ESP8266WiFi_nossl_noleak/src/include/ClientContext.h deleted file mode 100644 index 0e49b33..0000000 --- a/extras/ESP8266WiFi_nossl_noleak/src/include/ClientContext.h +++ /dev/null @@ -1,703 +0,0 @@ -/* - ClientContext.h - TCP connection handling on top of lwIP - - Copyright (c) 2014 Ivan Grokhotkov. All rights reserved. - This file is part of the esp8266 core for Arduino environment. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ -#ifndef CLIENTCONTEXT_H -#define CLIENTCONTEXT_H - -class ClientContext; -class WiFiClient; - -typedef void (*discard_cb_t)(void*, ClientContext*); - -extern "C" void esp_yield(); -extern "C" void esp_schedule(); - -#include "DataSource.h" -#include "lwip/priv/tcp_priv.h" - -//#define DEBUG_T(fmt, ...) ::printf((PGM_P)PSTR(fmt), ## __VA_ARGS__) -#define DEBUG_T(fmt, ...) - -bool getDefaultPrivateGlobalSyncValue (); - -class ClientContext -{ -public: - ClientContext(tcp_pcb* pcb, discard_cb_t discard_cb, void* discard_cb_arg) : - _pcb(pcb), _rx_buf(0), _rx_buf_offset(0), _discard_cb(discard_cb), _discard_cb_arg(discard_cb_arg), _refcnt(0), _next(0), - _sync(::getDefaultPrivateGlobalSyncValue()) - { - tcp_setprio(pcb, TCP_PRIO_MIN); - tcp_arg(pcb, this); - tcp_recv(pcb, &_s_recv); - tcp_sent(pcb, &_s_acked); - tcp_err(pcb, &_s_error); - tcp_poll(pcb, &_s_poll, 1); - - // keep-alive not enabled by default - //keepAlive(); - } - - err_t abort() - { - if(_pcb) { - DEBUGV(":abort\r\n"); - tcp_arg(_pcb, NULL); - tcp_sent(_pcb, NULL); - tcp_recv(_pcb, NULL); - tcp_err(_pcb, NULL); - tcp_poll(_pcb, NULL, 0); - tcp_abort(_pcb); - _pcb = nullptr; - } - return ERR_ABRT; - } - - err_t close() - { - err_t err = ERR_OK; - if(_pcb) { - DEBUGV(":close\r\n"); - tcp_arg(_pcb, NULL); - tcp_sent(_pcb, NULL); - tcp_recv(_pcb, NULL); - tcp_err(_pcb, NULL); - tcp_poll(_pcb, NULL, 0); - DEBUG_T(":tcp_close before: state %d\r\n", _pcb->state); // 4: ESTABLISHED - err = tcp_close(_pcb); - DEBUG_T(":tcp_close after: port %d, err %d, state %d\r\n", - _pcb->local_port ,(int) err, _pcb->state); // 5: FIN_WAIT_1 - /* - if(err != ERR_OK) { - DEBUGV(":tc err %d\r\n", (int) err); - tcp_abort(_pcb); - err = ERR_ABRT; - } - DEBUGV(":tcp_close call tcp_abandon\n"); - */ - tcp_abandon(_pcb, 0); - // tcp_abandon: (state!=CLOSED) - // 1. call tcp_pcb_remove { TCP_RMV, tcp_pcb_purge, set state = CLOSED } - // 2. free unacked and unsent (what we really want!) - // 3. send_rst (when arg1=1, do NOT do this here) - // 4. report ERR_ABRT - DEBUG_T(":tcp_abandon after: state %d\r\n", _pcb->state); // 0: CLOSED - _pcb = nullptr; - } - return err; - } - - ~ClientContext() - { - } - - ClientContext* next() const - { - return _next; - } - - ClientContext* next(ClientContext* new_next) - { - _next = new_next; - return _next; - } - - void ref() - { - ++_refcnt; - DEBUGV(":ref %d\r\n", _refcnt); - } - - void unref() - { - DEBUGV(":ur %d\r\n", _refcnt); - if(--_refcnt == 0) { - discard_received(); - close(); - if(_discard_cb) { - _discard_cb(_discard_cb_arg, this); - } - DEBUGV(":del\r\n"); - delete this; - } - } - - int connect(CONST ip_addr_t* addr, uint16_t port) - { - err_t err = tcp_connect(_pcb, addr, port, &ClientContext::_s_connected); - if (err != ERR_OK) { - return 0; - } - _connect_pending = true; - _op_start_time = millis(); - for (decltype(_timeout_ms) i = 0; _connect_pending && i < _timeout_ms; i++) { - // Give scheduled functions a chance to run (e.g. Ethernet uses recurrent) - delay(1); - // will resume on timeout or when _connected or _notify_error fires - } - _connect_pending = false; - if (!_pcb) { - DEBUGV(":cabrt\r\n"); - return 0; - } - if (state() != ESTABLISHED) { - DEBUGV(":ctmo\r\n"); - abort(); - return 0; - } - return 1; - } - - size_t availableForWrite() const - { - return _pcb? tcp_sndbuf(_pcb): 0; - } - - void setNoDelay(bool nodelay) - { - if(!_pcb) { - return; - } - if(nodelay) { - tcp_nagle_disable(_pcb); - } else { - tcp_nagle_enable(_pcb); - } - } - - bool getNoDelay() const - { - if(!_pcb) { - return false; - } - return tcp_nagle_disabled(_pcb); - } - - void setTimeout(int timeout_ms) - { - _timeout_ms = timeout_ms; - } - - int getTimeout() const - { - return _timeout_ms; - } - - const ip_addr_t* getRemoteAddress() const - { - if(!_pcb) { - return 0; - } - - return &_pcb->remote_ip; - } - - uint16_t getRemotePort() const - { - if(!_pcb) { - return 0; - } - - return _pcb->remote_port; - } - - const ip_addr_t* getLocalAddress() const - { - if(!_pcb) { - return 0; - } - - return &_pcb->local_ip; - } - - uint16_t getLocalPort() const - { - if(!_pcb) { - return 0; - } - - return _pcb->local_port; - } - - size_t getSize() const - { - if(!_rx_buf) { - return 0; - } - - return _rx_buf->tot_len - _rx_buf_offset; - } - - char read() - { - if(!_rx_buf) { - return 0; - } - - char c = reinterpret_cast(_rx_buf->payload)[_rx_buf_offset]; - _consume(1); - return c; - } - - size_t read(char* dst, size_t size) - { - if(!_rx_buf) { - return 0; - } - - size_t max_size = _rx_buf->tot_len - _rx_buf_offset; - size = (size < max_size) ? size : max_size; - - DEBUGV(":rd %d, %d, %d\r\n", size, _rx_buf->tot_len, _rx_buf_offset); - size_t size_read = 0; - while(size) { - size_t buf_size = _rx_buf->len - _rx_buf_offset; - size_t copy_size = (size < buf_size) ? size : buf_size; - DEBUGV(":rdi %d, %d\r\n", buf_size, copy_size); - os_memcpy(dst, reinterpret_cast(_rx_buf->payload) + _rx_buf_offset, copy_size); - dst += copy_size; - _consume(copy_size); - size -= copy_size; - size_read += copy_size; - } - return size_read; - } - - char peek() const - { - if(!_rx_buf) { - return 0; - } - - return reinterpret_cast(_rx_buf->payload)[_rx_buf_offset]; - } - - size_t peekBytes(char *dst, size_t size) const - { - if(!_rx_buf) { - return 0; - } - - size_t max_size = _rx_buf->tot_len - _rx_buf_offset; - size = (size < max_size) ? size : max_size; - - DEBUGV(":pd %d, %d, %d\r\n", size, _rx_buf->tot_len, _rx_buf_offset); - size_t buf_size = _rx_buf->len - _rx_buf_offset; - size_t copy_size = (size < buf_size) ? size : buf_size; - DEBUGV(":rpi %d, %d\r\n", buf_size, copy_size); - os_memcpy(dst, reinterpret_cast(_rx_buf->payload) + _rx_buf_offset, copy_size); - return copy_size; - } - - void discard_received() - { - if(!_rx_buf) { - return; - } - if(_pcb) { - tcp_recved(_pcb, (size_t) _rx_buf->tot_len); - } - pbuf_free(_rx_buf); - _rx_buf = 0; - _rx_buf_offset = 0; - } - - bool wait_until_sent(int max_wait_ms = WIFICLIENT_MAX_FLUSH_WAIT_MS) - { - // https://github.com/esp8266/Arduino/pull/3967#pullrequestreview-83451496 - // option 1 done - // option 2 / _write_some() not necessary since _datasource is always nullptr here - - if (!_pcb) - return true; - - int prevsndbuf = -1; - - // wait for peer's acks to flush lwIP's output buffer - uint32_t last_sent = millis(); - while (1) { - if (millis() - last_sent > (uint32_t) max_wait_ms) { -#ifdef DEBUGV - // wait until sent: timeout - DEBUGV(":wustmo\n"); -#endif - // All data was not flushed, timeout hit - return false; - } - - // force lwIP to send what can be sent - tcp_output(_pcb); - - int sndbuf = tcp_sndbuf(_pcb); - if (sndbuf != prevsndbuf) { - // send buffer has changed (or first iteration) - prevsndbuf = sndbuf; - // We just sent a bit, move timeout forward - last_sent = millis(); - } - - delay(0); // from sys or os context - - if ((state() != ESTABLISHED) || (sndbuf == TCP_SND_BUF)) { - break; - } - } - - // All data flushed - return true; - } - - uint8_t state() const - { - if(!_pcb) { - return CLOSED; - } - - return _pcb->state; - } - - size_t write(const uint8_t* data, size_t size) - { - if (!_pcb) { - return 0; - } - return _write_from_source(new BufferDataSource(data, size)); - } - - size_t write(Stream& stream) - { - if (!_pcb) { - return 0; - } - return _write_from_source(new BufferedStreamDataSource(stream, stream.available())); - } - - size_t write_P(PGM_P buf, size_t size) - { - if (!_pcb) { - return 0; - } - ProgmemStream stream(buf, size); - return _write_from_source(new BufferedStreamDataSource(stream, size)); - } - - void keepAlive (uint16_t idle_sec = TCP_DEFAULT_KEEPALIVE_IDLE_SEC, uint16_t intv_sec = TCP_DEFAULT_KEEPALIVE_INTERVAL_SEC, uint8_t count = TCP_DEFAULT_KEEPALIVE_COUNT) - { - if (idle_sec && intv_sec && count) { - _pcb->so_options |= SOF_KEEPALIVE; - _pcb->keep_idle = (uint32_t)1000 * idle_sec; - _pcb->keep_intvl = (uint32_t)1000 * intv_sec; - _pcb->keep_cnt = count; - } - else - _pcb->so_options &= ~SOF_KEEPALIVE; - } - - bool isKeepAliveEnabled () const - { - return !!(_pcb->so_options & SOF_KEEPALIVE); - } - - uint16_t getKeepAliveIdle () const - { - return isKeepAliveEnabled()? (_pcb->keep_idle + 500) / 1000: 0; - } - - uint16_t getKeepAliveInterval () const - { - return isKeepAliveEnabled()? (_pcb->keep_intvl + 500) / 1000: 0; - } - - uint8_t getKeepAliveCount () const - { - return isKeepAliveEnabled()? _pcb->keep_cnt: 0; - } - - bool getSync () const - { - return _sync; - } - - void setSync (bool sync) - { - _sync = sync; - } - -protected: - - bool _is_timeout() - { - return millis() - _op_start_time > _timeout_ms; - } - - void _notify_error() - { - if (_connect_pending || _send_waiting) { - _send_waiting = false; - _connect_pending = false; - esp_schedule(); // break delay in connect or _write_from_source - } - } - - size_t _write_from_source(DataSource* ds) - { - const size_t data_size = ds->available(); - assert(_datasource == nullptr); - assert(!_send_waiting); - _datasource = ds; - _written = 0; - _op_start_time = millis(); - do { - if (_write_some()) { - _op_start_time = millis(); - } - - if (!_datasource->available() || _is_timeout() || state() == CLOSED) { - if (_is_timeout()) { - DEBUGV(":wtmo\r\n"); - } - delete _datasource; - _datasource = nullptr; - break; - } - - _send_waiting = true; - for (decltype(_timeout_ms) i = 0; _send_waiting && i < _timeout_ms; i++) { - // Give scheduled functions a chance to run (e.g. Ethernet uses recurrent) - delay(1); - // will resume on timeout or when _write_some_from_cb or _notify_error fires - - } - _send_waiting = false; - } while(true); - - bool write_ok = true; - - if (_sync) { - write_ok = wait_until_sent(); - } else { - if (data_size != _written) { - write_ok = wait_until_sent(); - } - } - if (!write_ok){ - DEBUG_T(":tcp _write_from_source error, port: %d, call close.\n", _pcb->local_port); - close(); - } - - return _written; - } - - bool _write_some() - { - if (!_datasource || !_pcb) { - return false; - } - - DEBUGV(":wr %d %d\r\n", _datasource->available(), _written); - - bool has_written = false; - - while (_datasource) { - if (state() == CLOSED) - return false; - size_t next_chunk_size = std::min((size_t)tcp_sndbuf(_pcb), _datasource->available()); - if (!next_chunk_size) - break; - const uint8_t* buf = _datasource->get_buffer(next_chunk_size); - - uint8_t flags = 0; - if (next_chunk_size < _datasource->available()) - // PUSH is meant for peer, telling to give data to user app as soon as received - // PUSH "may be set" when sender has finished sending a "meaningful" data block - // PUSH does not break Nagle - // #5173: windows needs this flag - // more info: https://lists.gnu.org/archive/html/lwip-users/2009-11/msg00018.html - flags |= TCP_WRITE_FLAG_MORE; // do not tcp-PuSH (yet) - if (!_sync) - // user data must be copied when data are sent but not yet acknowledged - // (with sync, we wait for acknowledgment before returning to user) - flags |= TCP_WRITE_FLAG_COPY; - - err_t err = tcp_write(_pcb, buf, next_chunk_size, flags); - - DEBUGV(":wrc %d %d %d\r\n", next_chunk_size, _datasource->available(), (int)err); - - if (err == ERR_OK) { - _datasource->release_buffer(buf, next_chunk_size); - _written += next_chunk_size; - has_written = true; - } else { - // ERR_MEM(-1) is a valid error meaning - // "come back later". It leaves state() opened - break; - } - } - - if (has_written) - { - // lwIP's tcp_output doc: "Find out what we can send and send it" - // *with respect to Nagle* - // more info: https://lists.gnu.org/archive/html/lwip-users/2017-11/msg00134.html - tcp_output(_pcb); - } - - return has_written; - } - - void _write_some_from_cb() - { - if (_send_waiting) { - _send_waiting = false; - esp_schedule(); // break delay in _write_from_source - } - } - - err_t _acked(tcp_pcb* pcb, uint16_t len) - { - (void) pcb; - (void) len; - DEBUGV(":ack %d\r\n", len); - _write_some_from_cb(); - return ERR_OK; - } - - void _consume(size_t size) - { - if(_pcb) - tcp_recved(_pcb, size); - ptrdiff_t left = _rx_buf->len - _rx_buf_offset - size; - if(left > 0) { - _rx_buf_offset += size; - } else if(!_rx_buf->next) { - DEBUGV(":c0 %d, %d\r\n", size, _rx_buf->tot_len); - pbuf_free(_rx_buf); - _rx_buf = 0; - _rx_buf_offset = 0; - } else { - DEBUGV(":c %d, %d, %d\r\n", size, _rx_buf->len, _rx_buf->tot_len); - auto head = _rx_buf; - _rx_buf = _rx_buf->next; - _rx_buf_offset = 0; - pbuf_ref(_rx_buf); - pbuf_free(head); - } - } - - err_t _recv(tcp_pcb* pcb, pbuf* pb, err_t err) - { - (void) pcb; - (void) err; - if(pb == 0) { // connection closed - DEBUGV(":rcl\r\n"); - _notify_error(); - abort(); - return ERR_ABRT; - } - - if(_rx_buf) { - DEBUGV(":rch %d, %d\r\n", _rx_buf->tot_len, pb->tot_len); - pbuf_cat(_rx_buf, pb); - } else { - DEBUGV(":rn %d\r\n", pb->tot_len); - _rx_buf = pb; - _rx_buf_offset = 0; - } - return ERR_OK; - } - - void _error(err_t err) - { - (void) err; - DEBUGV(":er %d 0x%08x\r\n", (int) err, (uint32_t) _datasource); - tcp_arg(_pcb, NULL); - tcp_sent(_pcb, NULL); - tcp_recv(_pcb, NULL); - tcp_err(_pcb, NULL); - _pcb = nullptr; - _notify_error(); - } - - err_t _connected(struct tcp_pcb *pcb, err_t err) - { - (void) err; - (void) pcb; - assert(pcb == _pcb); - if (_connect_pending) { - _connect_pending = false; - esp_schedule(); // break delay in connect - } - return ERR_OK; - } - - err_t _poll(tcp_pcb*) - { - _write_some_from_cb(); - return ERR_OK; - } - - static err_t _s_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *pb, err_t err) - { - return reinterpret_cast(arg)->_recv(tpcb, pb, err); - } - - static void _s_error(void *arg, err_t err) - { - reinterpret_cast(arg)->_error(err); - } - - static err_t _s_poll(void *arg, struct tcp_pcb *tpcb) - { - return reinterpret_cast(arg)->_poll(tpcb); - } - - static err_t _s_acked(void *arg, struct tcp_pcb *tpcb, uint16_t len) - { - return reinterpret_cast(arg)->_acked(tpcb, len); - } - - static err_t _s_connected(void* arg, struct tcp_pcb *pcb, err_t err) - { - return reinterpret_cast(arg)->_connected(pcb, err); - } - -private: - tcp_pcb* _pcb; - - pbuf* _rx_buf; - size_t _rx_buf_offset; - - discard_cb_t _discard_cb; - void* _discard_cb_arg; - - DataSource* _datasource = nullptr; - size_t _written = 0; - uint32_t _timeout_ms = 5000; - uint32_t _op_start_time = 0; - bool _send_waiting = false; - bool _connect_pending = false; - - int8_t _refcnt; - ClientContext* _next; - - bool _sync; -}; - -#endif//CLIENTCONTEXT_H diff --git a/extras/ESP8266WiFi_nossl_noleak/src/include/DataSource.h b/extras/ESP8266WiFi_nossl_noleak/src/include/DataSource.h deleted file mode 100644 index 2a0bfed..0000000 --- a/extras/ESP8266WiFi_nossl_noleak/src/include/DataSource.h +++ /dev/null @@ -1,154 +0,0 @@ -/* DataSource.h - a read-only object similar to Stream, but with less methods - * Copyright (c) 2016 Ivan Grokhotkov. All rights reserved. - * This file is distributed under MIT license. - */ -#ifndef DATASOURCE_H -#define DATASOURCE_H - -#include - -class DataSource { -public: - virtual ~DataSource() {} - virtual size_t available() = 0; - virtual const uint8_t* get_buffer(size_t size) = 0; - virtual void release_buffer(const uint8_t* buffer, size_t size) = 0; - -}; - -class BufferDataSource : public DataSource { -public: - BufferDataSource(const uint8_t* data, size_t size) : - _data(data), - _size(size) - { - } - - size_t available() override - { - return _size - _pos; - } - - const uint8_t* get_buffer(size_t size) override - { - (void)size; - assert(_pos + size <= _size); - return _data + _pos; - } - - void release_buffer(const uint8_t* buffer, size_t size) override - { - (void)buffer; - assert(buffer == _data + _pos); - _pos += size; - } - -protected: - const uint8_t* _data; - const size_t _size; - size_t _pos = 0; -}; - -template -class BufferedStreamDataSource : public DataSource { -public: - BufferedStreamDataSource(TStream& stream, size_t size) : - _stream(stream), - _size(size) - { - } - - size_t available() override - { - return _size - _pos; - } - - const uint8_t* get_buffer(size_t size) override - { - assert(_pos + size <= _size); - - //Data that was already read from the stream but not released (e.g. if tcp_write error occured). Otherwise this should be 0. - const size_t stream_read = _streamPos - _pos; - - //Min required buffer size: max(requested size, previous stream data already in buffer) - const size_t min_buffer_size = size > stream_read ? size : stream_read; - - //Buffer too small? - if (_bufferSize < min_buffer_size) { - uint8_t *new_buffer = new uint8_t[min_buffer_size]; - //If stream reading is ahead, than some data is already in the old buffer and needs to be copied to new resized buffer - if (_buffer && stream_read > 0) { - memcpy(new_buffer, _buffer.get(), stream_read); - } - _buffer.reset(new_buffer); - _bufferSize = min_buffer_size; - } - - //Fetch remaining data from stream - //If error in tcp_write in ClientContext::_write_some() occured earlier and therefore release_buffer was not called last time, than the requested stream data is already in the buffer. - if (size > stream_read) { - //Remaining bytes to read from stream - const size_t stream_rem = size - stream_read; - const size_t cb = _stream.readBytes(reinterpret_cast(_buffer.get() + stream_read), stream_rem); - assert(cb == stream_rem); - (void)cb; - _streamPos += stream_rem; - } - return _buffer.get(); - - } - - void release_buffer(const uint8_t* buffer, size_t size) override - { - if (size == 0) { - return; - } - - (void)buffer; - _pos += size; - - //Cannot release more than acquired through get_buffer - assert(_pos <= _streamPos); - - //Release less than requested with get_buffer? - if (_pos < _streamPos) { - // Move unreleased stream data in buffer to front - assert(_buffer); - memmove(_buffer.get(), _buffer.get() + size, _streamPos - _pos); - } - } - -protected: - TStream & _stream; - std::unique_ptr _buffer; - size_t _size; - size_t _pos = 0; - size_t _bufferSize = 0; - size_t _streamPos = 0; -}; - -class ProgmemStream -{ -public: - ProgmemStream(PGM_P buf, size_t size) : - _buf(buf), - _left(size) - { - } - - size_t readBytes(char* dst, size_t size) - { - size_t will_read = (_left < size) ? _left : size; - memcpy_P((void*)dst, (PGM_VOID_P)_buf, will_read); - _left -= will_read; - _buf += will_read; - return will_read; - } - -protected: - PGM_P _buf; - size_t _left; -}; - - -#endif //DATASOURCE_H diff --git a/extras/ESP8266WiFi_nossl_noleak/src/include/SSLContext.h b/extras/ESP8266WiFi_nossl_noleak/src/include/SSLContext.h deleted file mode 100644 index f7d824f..0000000 --- a/extras/ESP8266WiFi_nossl_noleak/src/include/SSLContext.h +++ /dev/null @@ -1,441 +0,0 @@ -/* - SSLContext.h - Used by WiFiClientAxTLS - Copyright (c) 2015 Ivan Grokhotkov. All rights reserved. - This file is part of the esp8266 core for Arduino environment. - - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -*/ - -#ifndef SSLCONTEXT_H -#define SSLCONTEXT_H - -#define LWIP_INTERNAL - -extern "C" -{ -#include "osapi.h" -#include "ets_sys.h" -} -#include -#include -#include "lwip/opt.h" -#include "lwip/ip.h" -#include "lwip/tcp.h" -#include "lwip/inet.h" -#include "lwip/netif.h" -#include -#include -#include "c_types.h" - -namespace axTLS { - -typedef struct BufferItem -{ - BufferItem(const uint8_t* data_, size_t size_) - : size(size_), data(new uint8_t[size]) - { - if (data.get() != nullptr) { - memcpy(data.get(), data_, size); - } else { - DEBUGV(":wcs alloc %d failed\r\n", size_); - size = 0; - } - } - - size_t size; - std::unique_ptr data; -} BufferItem; - -typedef std::list BufferList; - -class SSLContext -{ -public: - SSLContext(bool isServer = false) - { - _isServer = isServer; - if (!_isServer) { - if (_ssl_client_ctx_refcnt == 0) { - _ssl_client_ctx = ssl_ctx_new(SSL_SERVER_VERIFY_LATER | SSL_DEBUG_OPTS | SSL_CONNECT_IN_PARTS | SSL_READ_BLOCKING | SSL_NO_DEFAULT_KEY, 0); - } - ++_ssl_client_ctx_refcnt; - } else { - if (_ssl_svr_ctx_refcnt == 0) { - _ssl_svr_ctx = ssl_ctx_new(SSL_SERVER_VERIFY_LATER | SSL_DEBUG_OPTS | SSL_CONNECT_IN_PARTS | SSL_READ_BLOCKING | SSL_NO_DEFAULT_KEY, 0); - } - ++_ssl_svr_ctx_refcnt; - } - } - - ~SSLContext() - { - if (io_ctx) { - io_ctx->unref(); - io_ctx = nullptr; - } - _ssl = nullptr; - if (!_isServer) { - --_ssl_client_ctx_refcnt; - if (_ssl_client_ctx_refcnt == 0) { - ssl_ctx_free(_ssl_client_ctx); - _ssl_client_ctx = nullptr; - } - } else { - --_ssl_svr_ctx_refcnt; - if (_ssl_svr_ctx_refcnt == 0) { - ssl_ctx_free(_ssl_svr_ctx); - _ssl_svr_ctx = nullptr; - } - } - } - - static void _delete_shared_SSL(SSL *_to_del) - { - ssl_free(_to_del); - } - - void connect(ClientContext* ctx, const char* hostName, uint32_t timeout_ms) - { - SSL_EXTENSIONS* ext = ssl_ext_new(); - ssl_ext_set_host_name(ext, hostName); - if (_ssl) { - /* Creating a new TLS session on top of a new TCP connection. - ssl_free will want to send a close notify alert, but the old TCP connection - is already gone at this point, so reset io_ctx. */ - io_ctx = nullptr; - _ssl = nullptr; - _available = 0; - _read_ptr = nullptr; - } - io_ctx = ctx; - ctx->ref(); - - // Wrap the new SSL with a smart pointer, custom deleter to call ssl_free - SSL *_new_ssl = ssl_client_new(_ssl_client_ctx, reinterpret_cast(this), nullptr, 0, ext); - std::shared_ptr _new_ssl_shared(_new_ssl, _delete_shared_SSL); - _ssl = _new_ssl_shared; - - uint32_t t = millis(); - - while (millis() - t < timeout_ms && ssl_handshake_status(_ssl.get()) != SSL_OK) { - uint8_t* data; - int rc = ssl_read(_ssl.get(), &data); - if (rc < SSL_OK) { - ssl_display_error(rc); - break; - } - } - } - - void connectServer(ClientContext *ctx, uint32_t timeout_ms) - { - io_ctx = ctx; - ctx->ref(); - - // Wrap the new SSL with a smart pointer, custom deleter to call ssl_free - SSL *_new_ssl = ssl_server_new(_ssl_svr_ctx, reinterpret_cast(this)); - std::shared_ptr _new_ssl_shared(_new_ssl, _delete_shared_SSL); - _ssl = _new_ssl_shared; - - uint32_t t = millis(); - - while (millis() - t < timeout_ms && ssl_handshake_status(_ssl.get()) != SSL_OK) { - uint8_t* data; - int rc = ssl_read(_ssl.get(), &data); - if (rc < SSL_OK) { - ssl_display_error(rc); - break; - } - } - } - - void stop() - { - if (io_ctx) { - io_ctx->unref(); - } - io_ctx = nullptr; - } - - bool connected() - { - if (_isServer) { - return _ssl != nullptr; - } else { - return _ssl != nullptr && ssl_handshake_status(_ssl.get()) == SSL_OK; - } - } - - int read(uint8_t* dst, size_t size) - { - if (!_available) { - if (!_readAll()) { - return 0; - } - } - size_t will_copy = (_available < size) ? _available : size; - memcpy(dst, _read_ptr, will_copy); - _read_ptr += will_copy; - _available -= will_copy; - if (_available == 0) { - _read_ptr = nullptr; - /* Send pending outgoing data, if any */ - if (_hasWriteBuffers()) { - _writeBuffersSend(); - } - } - return will_copy; - } - - int read() - { - if (!_available) { - if (!_readAll()) { - return -1; - } - } - int result = _read_ptr[0]; - ++_read_ptr; - --_available; - if (_available == 0) { - _read_ptr = nullptr; - /* Send pending outgoing data, if any */ - if (_hasWriteBuffers()) { - _writeBuffersSend(); - } - } - return result; - } - - int write(const uint8_t* src, size_t size) - { - if (_isServer) { - return _write(src, size); - } else if (!_available) { - if (_hasWriteBuffers()) { - int rc = _writeBuffersSend(); - if (rc < 0) { - return rc; - } - } - return _write(src, size); - } - /* Some received data is still present in the axtls fragment buffer. - We can't call ssl_write now, as that will overwrite the contents of - the fragment buffer, corrupting the received data. - Save a copy of the outgoing data, and call ssl_write when all - recevied data has been consumed by the application. - */ - return _writeBufferAdd(src, size); - } - - int peek() - { - if (!_available) { - if (!_readAll()) { - return -1; - } - } - return _read_ptr[0]; - } - - size_t peekBytes(char *dst, size_t size) - { - if (!_available) { - if (!_readAll()) { - return -1; - } - } - - size_t will_copy = (_available < size) ? _available : size; - memcpy(dst, _read_ptr, will_copy); - return will_copy; - } - - int available() - { - auto cb = _available; - if (cb == 0) { - cb = _readAll(); - } else { - optimistic_yield(100); - } - return cb; - } - - // similar to available, but doesn't return exact size - bool hasData() - { - return _available > 0 || (io_ctx && io_ctx->getSize() > 0); - } - - bool loadObject(int type, Stream& stream, size_t size) - { - std::unique_ptr buf(new uint8_t[size]); - if (!buf.get()) { - DEBUGV("loadObject: failed to allocate memory\n"); - return false; - } - - size_t cb = stream.readBytes(buf.get(), size); - if (cb != size) { - DEBUGV("loadObject: reading %u bytes, got %u\n", size, cb); - return false; - } - - return loadObject(type, buf.get(), size); - } - - bool loadObject_P(int type, PGM_VOID_P data, size_t size) - { - std::unique_ptr buf(new uint8_t[size]); - memcpy_P(buf.get(),data, size); - return loadObject(type, buf.get(), size); - } - - bool loadObject(int type, const uint8_t* data, size_t size) - { - int rc = ssl_obj_memory_load(_isServer?_ssl_svr_ctx:_ssl_client_ctx, type, data, static_cast(size), nullptr); - if (rc != SSL_OK) { - DEBUGV("loadObject: ssl_obj_memory_load returned %d\n", rc); - return false; - } - return true; - } - - bool verifyCert() - { - int rc = ssl_verify_cert(_ssl.get()); - if (_allowSelfSignedCerts && rc == SSL_X509_ERROR(X509_VFY_ERROR_SELF_SIGNED)) { - DEBUGV("Allowing self-signed certificate\n"); - return true; - } else if (rc != SSL_OK) { - DEBUGV("ssl_verify_cert returned %d\n", rc); - ssl_display_error(rc); - return false; - } - return true; - } - - void allowSelfSignedCerts() - { - _allowSelfSignedCerts = true; - } - - operator SSL*() - { - return _ssl.get(); - } - - static ClientContext* getIOContext(int fd) - { - if (fd) { - SSLContext *thisSSL = reinterpret_cast(fd); - return thisSSL->io_ctx; - } - return nullptr; - } - -protected: - int _readAll() - { - if (!_ssl) { - return 0; - } - - optimistic_yield(100); - - uint8_t* data; - int rc = ssl_read(_ssl.get(), &data); - if (rc <= 0) { - if (rc < SSL_OK && rc != SSL_CLOSE_NOTIFY && rc != SSL_ERROR_CONN_LOST) { - _ssl = nullptr; - } - return 0; - } - DEBUGV(":wcs ra %d\r\n", rc); - _read_ptr = data; - _available = rc; - return _available; - } - - int _write(const uint8_t* src, size_t size) - { - if (!_ssl) { - return 0; - } - - int rc = ssl_write(_ssl.get(), src, size); - if (rc >= 0) { - return rc; - } - DEBUGV(":wcs write rc=%d\r\n", rc); - return rc; - } - - int _writeBufferAdd(const uint8_t* data, size_t size) - { - if (!_ssl) { - return 0; - } - - _writeBuffers.emplace_back(data, size); - if (_writeBuffers.back().data.get() == nullptr) { - _writeBuffers.pop_back(); - return 0; - } - return size; - } - - int _writeBuffersSend() - { - while (!_writeBuffers.empty()) { - auto& first = _writeBuffers.front(); - int rc = _write(first.data.get(), first.size); - _writeBuffers.pop_front(); - if (rc < 0) { - if (_hasWriteBuffers()) { - DEBUGV(":wcs _writeBuffersSend dropping unsent data\r\n"); - _writeBuffers.clear(); - } - return rc; - } - } - return 0; - } - - bool _hasWriteBuffers() - { - return !_writeBuffers.empty(); - } - - bool _isServer = false; - static SSL_CTX* _ssl_client_ctx; - static int _ssl_client_ctx_refcnt; - static SSL_CTX* _ssl_svr_ctx; - static int _ssl_svr_ctx_refcnt; - std::shared_ptr _ssl = nullptr; - const uint8_t* _read_ptr = nullptr; - size_t _available = 0; - BufferList _writeBuffers; - bool _allowSelfSignedCerts = false; - ClientContext* io_ctx = nullptr; -}; - -}; // End namespace axTLS - -#endif diff --git a/extras/ESP8266WiFi_nossl_noleak/src/include/UdpContext.h b/extras/ESP8266WiFi_nossl_noleak/src/include/UdpContext.h deleted file mode 100644 index 31aa561..0000000 --- a/extras/ESP8266WiFi_nossl_noleak/src/include/UdpContext.h +++ /dev/null @@ -1,556 +0,0 @@ -/* - UdpContext.h - UDP connection handling on top of lwIP - - Copyright (c) 2014 Ivan Grokhotkov. All rights reserved. - This file is part of the esp8266 core for Arduino environment. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ -#ifndef UDPCONTEXT_H -#define UDPCONTEXT_H - -class UdpContext; - -extern "C" { -void esp_yield(); -void esp_schedule(); -#include "lwip/init.h" // LWIP_VERSION_ -#include -} - -#include - -#define PBUF_ALIGNER_ADJUST 4 -#define PBUF_ALIGNER(x) ((void*)((((intptr_t)(x))+3)&~3)) -#define PBUF_HELPER_FLAG 0xff // lwIP pbuf flag: u8_t - -class UdpContext -{ -public: - - typedef std::function rxhandler_t; - - UdpContext() - : _pcb(0) - , _rx_buf(0) - , _first_buf_taken(false) - , _rx_buf_offset(0) - , _refcnt(0) - , _tx_buf_head(0) - , _tx_buf_cur(0) - , _tx_buf_offset(0) - { - _pcb = udp_new(); -#ifdef LWIP_MAYBE_XCC - _mcast_ttl = 1; -#endif - } - - ~UdpContext() - { - udp_remove(_pcb); - _pcb = 0; - if (_tx_buf_head) - { - pbuf_free(_tx_buf_head); - _tx_buf_head = 0; - _tx_buf_cur = 0; - _tx_buf_offset = 0; - } - if (_rx_buf) - { - pbuf_free(_rx_buf); - _rx_buf = 0; - _rx_buf_offset = 0; - } - } - - void ref() - { - ++_refcnt; - } - - void unref() - { - DEBUGV(":ur %d\r\n", _refcnt); - if(--_refcnt == 0) { - delete this; - } - } - -#if LWIP_VERSION_MAJOR == 1 - - bool connect(IPAddress addr, uint16_t port) - { - _pcb->remote_ip = addr; - _pcb->remote_port = port; - return true; - } - - bool listen(IPAddress addr, uint16_t port) - { - udp_recv(_pcb, &_s_recv, (void *) this); - err_t err = udp_bind(_pcb, addr, port); - return err == ERR_OK; - } - -#else // lwIP-v2 - - bool connect(const IPAddress& addr, uint16_t port) - { - _pcb->remote_ip = addr; - _pcb->remote_port = port; - return true; - } - - bool listen(const IPAddress& addr, uint16_t port) - { - udp_recv(_pcb, &_s_recv, (void *) this); - err_t err = udp_bind(_pcb, addr, port); - return err == ERR_OK; - } - -#endif // lwIP-v2 - - void disconnect() - { - udp_disconnect(_pcb); - } - -#if LWIP_IPV6 - - void setMulticastInterface(IPAddress addr) - { - // Per 'udp_set_multicast_netif_addr()' signature and comments - // in lwIP sources: - // An IPv4 address designating a specific interface must be used. - // When an IPv6 address is given, the matching IPv4 in the same - // interface must be selected. - - if (!addr.isV4()) - { - for (auto a: addrList) - if (a.addr() == addr) - { - // found the IPv6 address, - // redirect parameter to IPv4 address in this interface - addr = a.ipv4(); - break; - } - assert(addr.isV4()); - } - udp_set_multicast_netif_addr(_pcb, ip_2_ip4((const ip_addr_t*)addr)); - } - -#else // !LWIP_IPV6 - - void setMulticastInterface(const IPAddress& addr) - { -#if LWIP_VERSION_MAJOR == 1 - udp_set_multicast_netif_addr(_pcb, (ip_addr_t)addr); -#else - udp_set_multicast_netif_addr(_pcb, ip_2_ip4((const ip_addr_t*)addr)); -#endif - } - -#endif // !LWIP_IPV6 - - void setMulticastTTL(int ttl) - { -#ifdef LWIP_MAYBE_XCC - _mcast_ttl = ttl; -#else - udp_set_multicast_ttl(_pcb, ttl); -#endif - } - - // warning: handler is called from tcp stack context - // esp_yield and non-reentrant functions which depend on it will fail - void onRx(rxhandler_t handler) { - _on_rx = handler; - } - - size_t getSize() const - { - if (!_rx_buf) - return 0; - - return _rx_buf->len - _rx_buf_offset; - } - - size_t tell() const - { - return _rx_buf_offset; - } - - void seek(const size_t pos) - { - assert(isValidOffset(pos)); - _rx_buf_offset = pos; - } - - bool isValidOffset(const size_t pos) const { - return (pos <= _rx_buf->len); - } - - CONST IPAddress& getRemoteAddress() CONST - { - return _currentAddr.srcaddr; - } - - uint16_t getRemotePort() const - { - return _currentAddr.srcport; - } - - const IPAddress& getDestAddress() const - { - return _currentAddr.dstaddr; - } - - uint16_t getLocalPort() const - { - if (!_pcb) - return 0; - return _pcb->local_port; - } - - bool next() - { - if (!_rx_buf) - return false; - if (!_first_buf_taken) - { - _first_buf_taken = true; - return true; - } - - auto deleteme = _rx_buf; - _rx_buf = _rx_buf->next; - - if (_rx_buf) - { - if (_rx_buf->flags == PBUF_HELPER_FLAG) - { - // we have interleaved informations on addresses within reception pbuf chain: - // before: (data-pbuf) -> (data-pbuf) -> (data-pbuf) -> ... in the receiving order - // now: (address-info-pbuf -> data-pbuf) -> (address-info-pbuf -> data-pbuf) -> ... - - // so the first rx_buf contains an address helper, - // copy it to "current address" - auto helper = (AddrHelper*)PBUF_ALIGNER(_rx_buf->payload); - _currentAddr = *helper; - - // destroy the helper in the about-to-be-released pbuf - helper->~AddrHelper(); - - // forward in rx_buf list, next one is effective data - // current (not ref'ed) one will be pbuf_free'd with deleteme - _rx_buf = _rx_buf->next; - } - - // this rx_buf is not nullptr by construction, - // ref'ing it to prevent release from the below pbuf_free(deleteme) - pbuf_ref(_rx_buf); - } - // remove the already-consumed head of the chain - pbuf_free(deleteme); - - _rx_buf_offset = 0; - return _rx_buf != nullptr; - } - - int read() - { - if (!_rx_buf || _rx_buf_offset >= _rx_buf->len) - return -1; - - char c = reinterpret_cast(_rx_buf->payload)[_rx_buf_offset]; - _consume(1); - return c; - } - - size_t read(char* dst, size_t size) - { - if (!_rx_buf) - return 0; - - size_t max_size = _rx_buf->len - _rx_buf_offset; - size = (size < max_size) ? size : max_size; - DEBUGV(":urd %d, %d, %d\r\n", size, _rx_buf->len, _rx_buf_offset); - - memcpy(dst, reinterpret_cast(_rx_buf->payload) + _rx_buf_offset, size); - _consume(size); - - return size; - } - - int peek() const - { - if (!_rx_buf || _rx_buf_offset == _rx_buf->len) - return -1; - - return reinterpret_cast(_rx_buf->payload)[_rx_buf_offset]; - } - - void flush() - { - //XXX this does not follow Arduino's flush definition - if (!_rx_buf) - return; - - _consume(_rx_buf->len - _rx_buf_offset); - } - - size_t append(const char* data, size_t size) - { - if (!_tx_buf_head || _tx_buf_head->tot_len < _tx_buf_offset + size) - { - _reserve(_tx_buf_offset + size); - } - if (!_tx_buf_head || _tx_buf_head->tot_len < _tx_buf_offset + size) - { - DEBUGV("failed _reserve"); - return 0; - } - - size_t left_to_copy = size; - while(left_to_copy) - { - // size already used in current pbuf - size_t used_cur = _tx_buf_offset - (_tx_buf_head->tot_len - _tx_buf_cur->tot_len); - size_t free_cur = _tx_buf_cur->len - used_cur; - if (free_cur == 0) - { - _tx_buf_cur = _tx_buf_cur->next; - continue; - } - size_t will_copy = (left_to_copy < free_cur) ? left_to_copy : free_cur; - memcpy(reinterpret_cast(_tx_buf_cur->payload) + used_cur, data, will_copy); - _tx_buf_offset += will_copy; - left_to_copy -= will_copy; - data += will_copy; - } - return size; - } - - bool send(CONST ip_addr_t* addr = 0, uint16_t port = 0) - { - size_t data_size = _tx_buf_offset; - pbuf* tx_copy = pbuf_alloc(PBUF_TRANSPORT, data_size, PBUF_RAM); - if(!tx_copy){ - DEBUGV("failed pbuf_alloc"); - } - else{ - uint8_t* dst = reinterpret_cast(tx_copy->payload); - for (pbuf* p = _tx_buf_head; p; p = p->next) { - size_t will_copy = (data_size < p->len) ? data_size : p->len; - memcpy(dst, p->payload, will_copy); - dst += will_copy; - data_size -= will_copy; - } - } - if (_tx_buf_head) - pbuf_free(_tx_buf_head); - _tx_buf_head = 0; - _tx_buf_cur = 0; - _tx_buf_offset = 0; - if(!tx_copy){ - return false; - } - - - if (!addr) { - addr = &_pcb->remote_ip; - port = _pcb->remote_port; - } -#ifdef LWIP_MAYBE_XCC - uint16_t old_ttl = _pcb->ttl; - if (ip_addr_ismulticast(addr)) { - _pcb->ttl = _mcast_ttl; - } -#endif - err_t err = udp_sendto(_pcb, tx_copy, addr, port); - if (err != ERR_OK) { - DEBUGV(":ust rc=%d\r\n", (int) err); - } -#ifdef LWIP_MAYBE_XCC - _pcb->ttl = old_ttl; -#endif - pbuf_free(tx_copy); - return err == ERR_OK; - } - -private: - - void _reserve(size_t size) - { - const size_t pbuf_unit_size = 128; - if (!_tx_buf_head) - { - _tx_buf_head = pbuf_alloc(PBUF_TRANSPORT, pbuf_unit_size, PBUF_RAM); - if (!_tx_buf_head) - { - return; - } - _tx_buf_cur = _tx_buf_head; - _tx_buf_offset = 0; - } - - size_t cur_size = _tx_buf_head->tot_len; - if (size < cur_size) - return; - - size_t grow_size = size - cur_size; - - while(grow_size) - { - pbuf* pb = pbuf_alloc(PBUF_TRANSPORT, pbuf_unit_size, PBUF_RAM); - if (!pb) - { - return; - } - pbuf_cat(_tx_buf_head, pb); - if (grow_size < pbuf_unit_size) - return; - grow_size -= pbuf_unit_size; - } - } - - void _consume(size_t size) - { - _rx_buf_offset += size; - if (_rx_buf_offset > _rx_buf->len) { - _rx_buf_offset = _rx_buf->len; - } - } - - void _recv(udp_pcb *upcb, pbuf *pb, - const ip_addr_t *srcaddr, u16_t srcport) - { - (void) upcb; - // check receive pbuf chain depth - { - pbuf* p; - int count = 0; - for (p = _rx_buf; p && ++count < rxBufMaxDepth*2; p = p->next); - if (p) - { - // pbuf chain too deep, dropping - pbuf_free(pb); - DEBUGV(":udr\r\n"); - return; - } - } - -#if LWIP_VERSION_MAJOR == 1 - #define TEMPDSTADDR (¤t_iphdr_dest) -#else - #define TEMPDSTADDR (ip_current_dest_addr()) -#endif - - // chain this helper pbuf first - if (_rx_buf) - { - // there is some unread data - // chain pbuf - - // Addresses/ports are stored from this callback because lwIP's - // macro are valid only now. - // - // When peeking data from before payload start (like it was done - // before IPv6), there's no easy way to safely guess whether - // packet is from v4 or v6. - // - // Now storing data in an intermediate chained pbuf containing - // AddrHelper - - // allocate new pbuf to store addresses/ports - pbuf* pb_helper = pbuf_alloc(PBUF_RAW, sizeof(AddrHelper) + PBUF_ALIGNER_ADJUST, PBUF_RAM); - if (!pb_helper) - { - // memory issue - discard received data - pbuf_free(pb); - return; - } - // construct in place - new(PBUF_ALIGNER(pb_helper->payload)) AddrHelper(srcaddr, TEMPDSTADDR, srcport); - pb_helper->flags = PBUF_HELPER_FLAG; // mark helper pbuf - // chain it - pbuf_cat(_rx_buf, pb_helper); - - // now chain the new data pbuf - DEBUGV(":urch %d, %d\r\n", _rx_buf->tot_len, pb->tot_len); - pbuf_cat(_rx_buf, pb); - } - else - { - _currentAddr.srcaddr = srcaddr; - _currentAddr.dstaddr = TEMPDSTADDR; - _currentAddr.srcport = srcport; - - DEBUGV(":urn %d\r\n", pb->tot_len); - _first_buf_taken = false; - _rx_buf = pb; - _rx_buf_offset = 0; - } - - if (_on_rx) { - _on_rx(); - } - - #undef TEMPDSTADDR - - } - - static void _s_recv(void *arg, - udp_pcb *upcb, pbuf *p, - CONST ip_addr_t *srcaddr, u16_t srcport) - { - reinterpret_cast(arg)->_recv(upcb, p, srcaddr, srcport); - } - -private: - udp_pcb* _pcb; - pbuf* _rx_buf; - bool _first_buf_taken; - size_t _rx_buf_offset; - int _refcnt; - pbuf* _tx_buf_head; - pbuf* _tx_buf_cur; - size_t _tx_buf_offset; - rxhandler_t _on_rx; -#ifdef LWIP_MAYBE_XCC - uint16_t _mcast_ttl; -#endif - struct AddrHelper - { - IPAddress srcaddr, dstaddr; - int16_t srcport; - - AddrHelper() { } - AddrHelper(const ip_addr_t* src, const ip_addr_t* dst, uint16_t srcport): - srcaddr(src), dstaddr(dst), srcport(srcport) { } - }; - AddrHelper _currentAddr; - - // rx pbuf depth barrier (counter of buffered UDP received packets) - // keep it small - static constexpr int rxBufMaxDepth = 4; -}; - - - -#endif//UDPCONTEXT_H diff --git a/extras/ESP8266WiFi_nossl_noleak/src/include/WiFiState.h b/extras/ESP8266WiFi_nossl_noleak/src/include/WiFiState.h deleted file mode 100644 index caceb6f..0000000 --- a/extras/ESP8266WiFi_nossl_noleak/src/include/WiFiState.h +++ /dev/null @@ -1,23 +0,0 @@ - -#ifndef WIFISTATE_H_ -#define WIFISTATE_H_ - -#include -#include - -struct WiFiState -{ - uint32_t crc; - struct - { - station_config fwconfig; - ip_info ip; - ip_addr_t dns[2]; - ip_addr_t ntp[2]; - WiFiMode_t mode; - uint8_t channel; - bool persistent; - } state; -}; - -#endif // WIFISTATE_H_ diff --git a/extras/ESP8266WiFi_nossl_noleak/src/include/slist.h b/extras/ESP8266WiFi_nossl_noleak/src/include/slist.h deleted file mode 100644 index 0606f72..0000000 --- a/extras/ESP8266WiFi_nossl_noleak/src/include/slist.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef SLIST_H -#define SLIST_H - -template -class SList { -public: - SList() : _next(0) { } - -protected: - - static void _add(T* self) { - T* tmp = _s_first; - _s_first = self; - self->_next = tmp; - } - - static void _remove(T* self) { - if (_s_first == self) { - _s_first = self->_next; - self->_next = 0; - return; - } - - for (T* prev = _s_first; prev->_next; prev = prev->_next) { - if (prev->_next == self) { - prev->_next = self->_next; - self->_next = 0; - return; - } - } - } - - static T* _s_first; - T* _next; -}; - - -#endif //SLIST_H diff --git a/extras/ESP8266WiFi_nossl_noleak/src/include/ssl.h b/extras/ESP8266WiFi_nossl_noleak/src/include/ssl.h deleted file mode 100644 index 8879e4c..0000000 --- a/extras/ESP8266WiFi_nossl_noleak/src/include/ssl.h +++ /dev/null @@ -1,583 +0,0 @@ -/* - * Copyright (c) 2007-2016, Cameron Rich - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * * Neither the name of the axTLS project nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * @mainpage axTLS API - * - * @image html axolotl.jpg - * - * The axTLS library has features such as: - * - The TLSv1 SSL client/server protocol - * - No requirement to use any openssl libraries. - * - A choice between AES block (128/256 bit) and RC4 (128 bit) stream ciphers. - * - RSA encryption/decryption with variable sized keys (up to 4096 bits). - * - Certificate chaining and peer authentication. - * - Session resumption, session renegotiation. - * - ASN.1, X.509, PKCS#8, PKCS#12 keys/certificates with DER/PEM encoding. - * - Highly configurable compile time options. - * - Portable across many platforms (written in ANSI C), and has language - * bindings in C, C#, VB.NET, Java, Perl and Lua. - * - Partial openssl API compatibility (via a wrapper). - * - A very small footprint (around 50-60kB for the library in 'server-only' - * mode). - * - No dependencies on sockets - can use serial connections for example. - * - A very simple API - ~ 20 functions/methods. - * - * A list of these functions/methods are described below. - * - * @ref c_api - * - * @ref bigint_api - * - * @ref csharp_api - * - * @ref java_api - */ -#ifndef HEADER_SSL_H -#define HEADER_SSL_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* need to predefine before ssl_lib.h gets to it */ -#define SSL_SESSION_ID_SIZE 32 - -#define EXP_FUNC -#define STDCALL -// struct SSL_CTX_; -typedef struct SSL_CTX_ SSL_CTX; -typedef struct SSL_ SSL; -typedef struct SSL_EXTENSIONS_ SSL_EXTENSIONS; - -/* The optional parameters that can be given to the client/server SSL engine */ -#define SSL_CLIENT_AUTHENTICATION 0x00010000 -#define SSL_SERVER_VERIFY_LATER 0x00020000 -#define SSL_NO_DEFAULT_KEY 0x00040000 -#define SSL_DISPLAY_STATES 0x00080000 -#define SSL_DISPLAY_BYTES 0x00100000 -#define SSL_DISPLAY_CERTS 0x00200000 -#define SSL_DISPLAY_RSA 0x00400000 -#define SSL_CONNECT_IN_PARTS 0x00800000 -#define SSL_READ_BLOCKING 0x01000000 - -/* errors that can be generated */ -#define SSL_OK 0 -#define SSL_NOT_OK -1 -#define SSL_ERROR_DEAD -2 -#define SSL_CLOSE_NOTIFY -3 -#define SSL_ERROR_CONN_LOST -256 -#define SSL_ERROR_RECORD_OVERFLOW -257 -#define SSL_ERROR_SOCK_SETUP_FAILURE -258 -#define SSL_ERROR_INVALID_HANDSHAKE -260 -#define SSL_ERROR_INVALID_PROT_MSG -261 -#define SSL_ERROR_INVALID_HMAC -262 -#define SSL_ERROR_INVALID_VERSION -263 -#define SSL_ERROR_UNSUPPORTED_EXTENSION -264 -#define SSL_ERROR_INVALID_SESSION -265 -#define SSL_ERROR_NO_CIPHER -266 -#define SSL_ERROR_INVALID_CERT_HASH_ALG -267 -#define SSL_ERROR_BAD_CERTIFICATE -268 -#define SSL_ERROR_INVALID_KEY -269 -#define SSL_ERROR_FINISHED_INVALID -271 -#define SSL_ERROR_NO_CERT_DEFINED -272 -#define SSL_ERROR_NO_CLIENT_RENOG -273 -#define SSL_ERROR_NOT_SUPPORTED -274 -#define SSL_X509_OFFSET -512 -#define SSL_X509_ERROR(A) (SSL_X509_OFFSET+A) - -#define X509_OK 0 -#define X509_NOT_OK -1 -#define X509_VFY_ERROR_NO_TRUSTED_CERT -2 -#define X509_VFY_ERROR_BAD_SIGNATURE -3 -#define X509_VFY_ERROR_NOT_YET_VALID -4 -#define X509_VFY_ERROR_EXPIRED -5 -#define X509_VFY_ERROR_SELF_SIGNED -6 -#define X509_VFY_ERROR_INVALID_CHAIN -7 -#define X509_VFY_ERROR_UNSUPPORTED_DIGEST -8 -#define X509_INVALID_PRIV_KEY -9 -#define X509_MAX_CERTS -10 -#define X509_VFY_ERROR_BASIC_CONSTRAINT -11 - -/* alert types that are recognized */ -#define SSL_ALERT_TYPE_WARNING 1 -#define SLL_ALERT_TYPE_FATAL 2 - -/* these are all the alerts that are recognized */ -#define SSL_ALERT_CLOSE_NOTIFY 0 -#define SSL_ALERT_UNEXPECTED_MESSAGE 10 -#define SSL_ALERT_BAD_RECORD_MAC 20 -#define SSL_ALERT_RECORD_OVERFLOW 22 -#define SSL_ALERT_HANDSHAKE_FAILURE 40 -#define SSL_ALERT_BAD_CERTIFICATE 42 -#define SSL_ALERT_UNSUPPORTED_CERTIFICATE 43 -#define SSL_ALERT_CERTIFICATE_EXPIRED 45 -#define SSL_ALERT_CERTIFICATE_UNKNOWN 46 -#define SSL_ALERT_ILLEGAL_PARAMETER 47 -#define SSL_ALERT_UNKNOWN_CA 48 -#define SSL_ALERT_DECODE_ERROR 50 -#define SSL_ALERT_DECRYPT_ERROR 51 -#define SSL_ALERT_INVALID_VERSION 70 -#define SSL_ALERT_NO_RENEGOTIATION 100 -#define SSL_ALERT_UNSUPPORTED_EXTENSION 110 - -/* The ciphers that are supported */ -#define SSL_AES128_SHA 0x2f -#define SSL_AES256_SHA 0x35 -#define SSL_AES128_SHA256 0x3c -#define SSL_AES256_SHA256 0x3d - -/* build mode ids' */ -#define SSL_BUILD_SKELETON_MODE 0x01 -#define SSL_BUILD_SERVER_ONLY 0x02 -#define SSL_BUILD_ENABLE_VERIFICATION 0x03 -#define SSL_BUILD_ENABLE_CLIENT 0x04 -#define SSL_BUILD_FULL_MODE 0x05 - -/* offsets to retrieve configuration information */ -#define SSL_BUILD_MODE 0 -#define SSL_MAX_CERT_CFG_OFFSET 1 -#define SSL_MAX_CA_CERT_CFG_OFFSET 2 -#define SSL_HAS_PEM 3 - -/* default session sizes */ -#define SSL_DEFAULT_SVR_SESS 5 -#define SSL_DEFAULT_CLNT_SESS 1 - -/* X.509/X.520 distinguished name types */ -#define SSL_X509_CERT_COMMON_NAME 0 -#define SSL_X509_CERT_ORGANIZATION 1 -#define SSL_X509_CERT_ORGANIZATIONAL_NAME 2 -#define SSL_X509_CA_CERT_COMMON_NAME 3 -#define SSL_X509_CA_CERT_ORGANIZATION 4 -#define SSL_X509_CA_CERT_ORGANIZATIONAL_NAME 5 - -/* SSL object loader types */ -#define SSL_OBJ_X509_CERT 1 -#define SSL_OBJ_X509_CACERT 2 -#define SSL_OBJ_RSA_KEY 3 -#define SSL_OBJ_PKCS8 4 -#define SSL_OBJ_PKCS12 5 - -/** - * @defgroup c_api Standard C API - * @brief The standard interface in C. - * @{ - */ - -/** - * @brief Establish a new client/server context. - * - * This function is called before any client/server SSL connections are made. - * - * Each new connection will use the this context's private key and - * certificate chain. If a different certificate chain is required, then a - * different context needs to be be used. - * - * There are two threading models supported - a single thread with one - * SSL_CTX can support any number of SSL connections - and multiple threads can - * support one SSL_CTX object each (the default). But if a single SSL_CTX - * object uses many SSL objects in individual threads, then the - * CONFIG_SSL_CTX_MUTEXING option needs to be configured. - * - * @param options [in] Any particular options. At present the options - * supported are: - * - SSL_SERVER_VERIFY_LATER (client only): Don't stop a handshake if the server - * authentication fails. The certificate can be authenticated later with a - * call to ssl_verify_cert(). - * - SSL_CLIENT_AUTHENTICATION (server only): Enforce client authentication - * i.e. each handshake will include a "certificate request" message from the - * server. Only available if verification has been enabled. - * - SSL_DISPLAY_BYTES (full mode build only): Display the byte sequences - * during the handshake. - * - SSL_DISPLAY_STATES (full mode build only): Display the state changes - * during the handshake. - * - SSL_DISPLAY_CERTS (full mode build only): Display the certificates that - * are passed during a handshake. - * - SSL_DISPLAY_RSA (full mode build only): Display the RSA key details that - * are passed during a handshake. - * - SSL_CONNECT_IN_PARTS (client only): To use a non-blocking version of - * ssl_client_new(). - * @param num_sessions [in] The number of sessions to be used for session - * caching. If this value is 0, then there is no session caching. This option - * is not used in skeleton mode. - * @return A client/server context. - */ -EXP_FUNC SSL_CTX * STDCALL ssl_ctx_new(uint32_t options, int num_sessions); - -/** - * @brief Remove a client/server context. - * - * Frees any used resources used by this context. Each connection will be - * sent a "Close Notify" alert (if possible). - * @param ssl_ctx [in] The client/server context. - */ -EXP_FUNC void STDCALL ssl_ctx_free(SSL_CTX *ssl_ctx); - -/** - * @brief Allocates new SSL extensions structure and returns pointer to it - * - * @return ssl_ext Pointer to SSL_EXTENSIONS structure - * - */ -EXP_FUNC SSL_EXTENSIONS * STDCALL ssl_ext_new(); - -/** - * @brief Set the host name for SNI extension - * @param ssl_ext pointer returned by ssl_ext_new - * @param host_name pointer to a zero-terminated string containing host name - */ -EXP_FUNC void STDCALL ssl_ext_set_host_name(SSL_EXTENSIONS * ext, const char* host_name); - -/** - * @brief Set the maximum fragment size for the fragment size negotiation extension - * @param ssl_ext pointer returned by ssl_ext_new - * @param fragment_size fragment size, allowed values: 2^9, 2^10 ... 2^14 - */ -EXP_FUNC void STDCALL ssl_ext_set_max_fragment_size(SSL_EXTENSIONS * ext, unsigned fragment_size); - -/** - * @brief Frees SSL extensions structure - * - * @param ssl_ext [in] Pointer to SSL_EXTENSION structure - * - */ -EXP_FUNC void STDCALL ssl_ext_free(SSL_EXTENSIONS *ssl_ext); - -/** - * @brief (server only) Establish a new SSL connection to an SSL client. - * - * It is up to the application to establish the logical connection (whether it - * is a socket, serial connection etc). - * @param ssl_ctx [in] The server context. - * @param client_fd [in] The client's file descriptor. - * @return An SSL object reference. - */ -EXP_FUNC SSL * STDCALL ssl_server_new(SSL_CTX *ssl_ctx, int client_fd); - -/** - * @brief (client only) Establish a new SSL connection to an SSL server. - * - * It is up to the application to establish the initial logical connection - * (whether it is a socket, serial connection etc). - * - * This is a normally a blocking call - it will finish when the handshake is - * complete (or has failed). To use in non-blocking mode, set - * SSL_CONNECT_IN_PARTS in ssl_ctx_new(). - * @param ssl_ctx [in] The client context. - * @param client_fd [in] The client's file descriptor. - * @param session_id [in] A 32 byte session id for session resumption. This - * can be null if no session resumption is being used or required. This option - * is not used in skeleton mode. - * @param sess_id_size The size of the session id (max 32) - * @param ssl_ext pointer to a structure with the activated SSL extensions and their values - * @return An SSL object reference. Use ssl_handshake_status() to check - * if a handshake succeeded. - */ -EXP_FUNC SSL * STDCALL ssl_client_new(SSL_CTX *ssl_ctx, int client_fd, const uint8_t *session_id, uint8_t sess_id_size, SSL_EXTENSIONS* ssl_ext); - -/** - * @brief Free any used resources on this connection. - - * A "Close Notify" message is sent on this connection (if possible). It is up - * to the application to close the socket or file descriptor. - * @param ssl [in] The ssl object reference. - */ -EXP_FUNC void STDCALL ssl_free(SSL *ssl); - -/** - * @brief Read the SSL data stream. - * If the socket is non-blocking and data is blocked then SSO_OK will be - * returned. - * @param ssl [in] An SSL object reference. - * @param in_data [out] If the read was successful, a pointer to the read - * buffer will be here. Do NOT ever free this memory as this buffer is used in - * sucessive calls. If the call was unsuccessful, this value will be null. - * @return The number of decrypted bytes: - * - if > 0, then the handshaking is complete and we are returning the number - * of decrypted bytes. - * - SSL_OK if the handshaking stage is successful (but not yet complete). - * - < 0 if an error. - * @see ssl.h for the error code list. - * @note Use in_data before doing any successive ssl calls. - */ -EXP_FUNC int STDCALL ssl_read(SSL *ssl, uint8_t **in_data); - -/** - * @brief Write to the SSL data stream. - * if the socket is non-blocking and data is blocked then a check is made - * to ensure that all data is sent (i.e. blocked mode is forced). - * @param ssl [in] An SSL obect reference. - * @param out_data [in] The data to be written - * @param out_len [in] The number of bytes to be written. - * @return The number of bytes sent, or if < 0 if an error. - * @see ssl.h for the error code list. - */ -EXP_FUNC int STDCALL ssl_write(SSL *ssl, const uint8_t *out_data, int out_len); - -/** - * @brief Calculate the size of the encrypted data from what you are about to send - * @param ssl [in] An SSL obect reference. - * @param out_len [in] The number of bytes to be written. - * @return The number of bytes that will be sent, or if < 0 if an error. - * @see ssl.h for the error code list. - */ -EXP_FUNC int STDCALL ssl_calculate_write_length(SSL *ssl, int out_len); - -/** - * @brief Find an ssl object based on a file descriptor. - * - * Goes through the list of SSL objects maintained in a client/server context - * to look for a file descriptor match. - * @param ssl_ctx [in] The client/server context. - * @param client_fd [in] The file descriptor. - * @return A reference to the SSL object. Returns null if the object could not - * be found. - */ -EXP_FUNC SSL * STDCALL ssl_find(SSL_CTX *ssl_ctx, int client_fd); - -/** - * @brief Get the session id for a handshake. - * - * This will be a 32 byte sequence and is available after the first - * handshaking messages are sent. - * @param ssl [in] An SSL object reference. - * @return The session id as a 32 byte sequence. - * @note A SSLv23 handshake may have only 16 valid bytes. - */ -EXP_FUNC const uint8_t * STDCALL ssl_get_session_id(const SSL *ssl); - -/** - * @brief Get the session id size for a handshake. - * - * This will normally be 32 but could be 0 (no session id) or something else. - * @param ssl [in] An SSL object reference. - * @return The size of the session id. - */ -EXP_FUNC uint8_t STDCALL ssl_get_session_id_size(const SSL *ssl); - -/** - * @brief Return the cipher id (in the SSL form). - * @param ssl [in] An SSL object reference. - * @return The cipher id. This will be one of the following: - * - SSL_AES128_SHA (0x2f) - * - SSL_AES256_SHA (0x35) - * - SSL_RC4_128_SHA (0x05) - * - SSL_RC4_128_MD5 (0x04) - */ -EXP_FUNC uint8_t STDCALL ssl_get_cipher_id(const SSL *ssl); - -/** - * @brief Return the status of the handshake. - * @param ssl [in] An SSL object reference. - * @return SSL_OK if the handshake is complete and ok. - * @see ssl.h for the error code list. - */ -EXP_FUNC int STDCALL ssl_handshake_status(const SSL *ssl); - -/** - * @brief Retrieve various parameters about the axTLS engine. - * @param offset [in] The configuration offset. It will be one of the following: - * - SSL_BUILD_MODE The build mode. This will be one of the following: - * - SSL_BUILD_SERVER_ONLY (basic server mode) - * - SSL_BUILD_ENABLE_VERIFICATION (server can do client authentication) - * - SSL_BUILD_ENABLE_CLIENT (client/server capabilties) - * - SSL_BUILD_FULL_MODE (client/server with diagnostics) - * - SSL_BUILD_SKELETON_MODE (skeleton mode) - * - SSL_MAX_CERT_CFG_OFFSET The maximum number of certificates allowed. - * - SSL_MAX_CA_CERT_CFG_OFFSET The maximum number of CA certificates allowed. - * - SSL_HAS_PEM 1 if supported - * @return The value of the requested parameter. - */ -EXP_FUNC int STDCALL ssl_get_config(int offset); - -/** - * @brief Display why the handshake failed. - * - * This call is only useful in a 'full mode' build. The output is to stdout. - * @param error_code [in] An error code. - * @see ssl.h for the error code list. - */ -EXP_FUNC void STDCALL ssl_display_error(int error_code); - -/** - * @brief Authenticate a received certificate. - * - * This call is usually made by a client after a handshake is complete and the - * context is in SSL_SERVER_VERIFY_LATER mode. - * @param ssl [in] An SSL object reference. - * @return SSL_OK if the certificate is verified. - */ -EXP_FUNC int STDCALL ssl_verify_cert(const SSL *ssl); - -/** - * @brief Check if certificate fingerprint (SHA1) matches the one given. - * - * @param ssl [in] An SSL object reference. - * @param fp [in] SHA1 fingerprint to match against - * @return SSL_OK if the certificate is verified. - */ -EXP_FUNC int STDCALL ssl_match_fingerprint(const SSL *ssl, const uint8_t* fp); - -/** - * @brief Check if SHA256 hash of Subject Public Key Info matches the one given. - * - * @param ssl [in] An SSL object reference. - * @param fp [in] SHA256 hash to match against - * @return SSL_OK if the certificate is verified. - */ -EXP_FUNC int STDCALL ssl_match_spki_sha256(const SSL *ssl, const uint8_t* hash); - -/** - * @brief Retrieve an X.509 distinguished name component. - * - * When a handshake is complete and a certificate has been exchanged, then the - * details of the remote certificate can be retrieved. - * - * This will usually be used by a client to check that the server's common - * name matches the URL. - * - * @param ssl [in] An SSL object reference. - * @param component [in] one of: - * - SSL_X509_CERT_COMMON_NAME - * - SSL_X509_CERT_ORGANIZATION - * - SSL_X509_CERT_ORGANIZATIONAL_NAME - * - SSL_X509_CA_CERT_COMMON_NAME - * - SSL_X509_CA_CERT_ORGANIZATION - * - SSL_X509_CA_CERT_ORGANIZATIONAL_NAME - * @return The appropriate string (or null if not defined) - * @note Verification build mode must be enabled. - */ -EXP_FUNC const char * STDCALL ssl_get_cert_dn(const SSL *ssl, int component); - -/** - * @brief Retrieve a Subject Alternative DNSName - * - * When a handshake is complete and a certificate has been exchanged, then the - * details of the remote certificate can be retrieved. - * - * This will usually be used by a client to check that the server's DNS - * name matches the URL. - * - * @param ssl [in] An SSL object reference. - * @param dnsindex [in] The index of the DNS name to retrieve. - * @return The appropriate string (or null if not defined) - * @note Verification build mode must be enabled. - */ -EXP_FUNC const char * STDCALL ssl_get_cert_subject_alt_dnsname(const SSL *ssl, int dnsindex); - -/** - * @brief Force the client to perform its handshake again. - * - * For a client this involves sending another "client hello" message. - * For the server is means sending a "hello request" message. - * - * This is a blocking call on the client (until the handshake completes). - * - * @param ssl [in] An SSL object reference. - * @return SSL_OK if renegotiation instantiation was ok - */ -EXP_FUNC int STDCALL ssl_renegotiate(SSL *ssl); - -/** - * @brief Process a file that is in binary DER or ASCII PEM format. - * - * These are temporary objects that are used to load private keys, - * certificates etc into memory. - * @param ssl_ctx [in] The client/server context. - * @param obj_type [in] The format of the file. Can be one of: - * - SSL_OBJ_X509_CERT (no password required) - * - SSL_OBJ_X509_CACERT (no password required) - * - SSL_OBJ_RSA_KEY (AES128/AES256 PEM encryption supported) - * - SSL_OBJ_PKCS8 (RC4-128 encrypted data supported) - * - SSL_OBJ_PKCS12 (RC4-128 encrypted data supported) - * - * PEM files are automatically detected (if supported). The object type is - * also detected, and so is not relevant for these types of files. - * @param filename [in] The location of a file in DER/PEM format. - * @param password [in] The password used. Can be null if not required. - * @return SSL_OK if all ok - * @note Not available in skeleton build mode. - */ -EXP_FUNC int STDCALL ssl_obj_load(SSL_CTX *ssl_ctx, int obj_type, const char *filename, const char *password); - -/** - * @brief Process binary data. - * - * These are temporary objects that are used to load private keys, - * certificates etc into memory. - * @param ssl_ctx [in] The client/server context. - * @param obj_type [in] The format of the memory data. - * @param data [in] The binary data to be loaded. - * @param len [in] The amount of data to be loaded. - * @param password [in] The password used. Can be null if not required. - * @return SSL_OK if all ok - * @see ssl_obj_load for more details on obj_type. - */ -EXP_FUNC int STDCALL ssl_obj_memory_load(SSL_CTX *ssl_ctx, int obj_type, const uint8_t *data, int len, const char *password); - -#ifdef CONFIG_SSL_GENERATE_X509_CERT -/** - * @brief Create an X.509 certificate. - * - * This certificate is a self-signed v1 cert with a fixed start/stop validity - * times. It is signed with an internal private key in ssl_ctx. - * - * @param ssl_ctx [in] The client/server context. - * @param options [in] Not used yet. - * @param dn [in] An array of distinguished name strings. The array is defined - * by: - * - SSL_X509_CERT_COMMON_NAME (0) - * - If SSL_X509_CERT_COMMON_NAME is empty or not defined, then the - * hostname will be used. - * - SSL_X509_CERT_ORGANIZATION (1) - * - If SSL_X509_CERT_ORGANIZATION is empty or not defined, then $USERNAME - * will be used. - * - SSL_X509_CERT_ORGANIZATIONAL_NAME (2) - * - SSL_X509_CERT_ORGANIZATIONAL_NAME is optional. - * @param cert_data [out] The certificate as a sequence of bytes. - * @return < 0 if an error, or the size of the certificate in bytes. - * @note cert_data must be freed when there is no more need for it. - */ -EXP_FUNC int STDCALL ssl_x509_create(SSL_CTX *ssl_ctx, uint32_t options, const char * dn[], uint8_t **cert_data); -#endif - -/** - * @brief Return the axTLS library version as a string. - */ -EXP_FUNC const char * STDCALL ssl_version(void); - -/** @} */ - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/extras/ESP8266WiFi_nossl_noleak/src/include/wl_definitions.h b/extras/ESP8266WiFi_nossl_noleak/src/include/wl_definitions.h deleted file mode 100644 index 5c8c536..0000000 --- a/extras/ESP8266WiFi_nossl_noleak/src/include/wl_definitions.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - wl_definitions.h - Library for Arduino Wifi shield. - Copyright (c) 2011-2014 Arduino. All right reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ -/* - * wl_definitions.h - * - * Created on: Mar 6, 2011 - * Author: dlafauci - */ - -#ifndef WL_DEFINITIONS_H_ -#define WL_DEFINITIONS_H_ - -// Maximum size of a SSID -#define WL_SSID_MAX_LENGTH 32 -// Length of passphrase. Valid lengths are 8-63. -#define WL_WPA_KEY_MAX_LENGTH 63 -// Length of key in bytes. Valid values are 5 and 13. -#define WL_WEP_KEY_MAX_LENGTH 13 -// Size of a MAC-address or BSSID -#define WL_MAC_ADDR_LENGTH 6 -// Size of a MAC-address or BSSID -#define WL_IPV4_LENGTH 4 -// Maximum size of a SSID list -#define WL_NETWORKS_LIST_MAXNUM 10 -// Maxmium number of socket -#define MAX_SOCK_NUM 4 -// Socket not available constant -#define SOCK_NOT_AVAIL 255 -// Default state value for Wifi state field -#define NA_STATE -1 -//Maximum number of attempts to establish wifi connection -#define WL_MAX_ATTEMPT_CONNECTION 10 - -typedef enum { - WL_NO_SHIELD = 255, // for compatibility with WiFi Shield library - WL_IDLE_STATUS = 0, - WL_NO_SSID_AVAIL = 1, - WL_SCAN_COMPLETED = 2, - WL_CONNECTED = 3, - WL_CONNECT_FAILED = 4, - WL_CONNECTION_LOST = 5, - WL_DISCONNECTED = 6 -} wl_status_t; - -/* Encryption modes */ -enum wl_enc_type { /* Values map to 802.11 encryption suites... */ - ENC_TYPE_WEP = 5, - ENC_TYPE_TKIP = 2, - ENC_TYPE_CCMP = 4, - /* ... except these two, 7 and 8 are reserved in 802.11-2007 */ - ENC_TYPE_NONE = 7, - ENC_TYPE_AUTO = 8 -}; - -#if !defined(LWIP_INTERNAL) && !defined(__LWIP_TCP_H__) -enum wl_tcp_state { - CLOSED = 0, - LISTEN = 1, - SYN_SENT = 2, - SYN_RCVD = 3, - ESTABLISHED = 4, - FIN_WAIT_1 = 5, - FIN_WAIT_2 = 6, - CLOSE_WAIT = 7, - CLOSING = 8, - LAST_ACK = 9, - TIME_WAIT = 10 -}; -#endif - -#endif /* WL_DEFINITIONS_H_ */ From d738ad0f30e91a37ee9ffffebe2e76bfa8ff2537 Mon Sep 17 00:00:00 2001 From: David Kerr Date: Sat, 8 Jun 2024 11:22:28 -0400 Subject: [PATCH 15/34] Handle case where wifiClient IP addresses may not be set --- src/arduino_homekit_server.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/arduino_homekit_server.cpp b/src/arduino_homekit_server.cpp index df0516a..a54a360 100644 --- a/src/arduino_homekit_server.cpp +++ b/src/arduino_homekit_server.cpp @@ -2987,6 +2987,13 @@ client_context_t* homekit_server_accept_client(homekit_server_t *server) { delete wifiClient; return NULL; } + if (!wifiClient->localIP().isSet() || + !wifiClient->remoteIP().isSet()) { + INFO("wifiClient creation error, IP address is not set"); + wifiClient->stop(); + delete wifiClient; + return NULL; + } } else { return NULL; } From 7a1d21abb21da76ea0cf7e0e1d486da87046de9b Mon Sep 17 00:00:00 2001 From: David Kerr Date: Sat, 8 Jun 2024 11:25:00 -0400 Subject: [PATCH 16/34] Allocate encrypted buffer on the heap instead of the stack, courtesy of @jgstroud Attempting to use 1KB from stack is risky as the ESP8266 has very small stack to start with. --- src/arduino_homekit_server.cpp | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/arduino_homekit_server.cpp b/src/arduino_homekit_server.cpp index a54a360..80fbb15 100644 --- a/src/arduino_homekit_server.cpp +++ b/src/arduino_homekit_server.cpp @@ -561,8 +561,10 @@ int client_send_encrypted_(client_context_t *context, byte nonce[12]; memset(nonce, 0, sizeof(nonce)); - byte encrypted[1024 + 18]; - uint payload_offset = 0; +#define ENCRYPTED_BUFFER_SIZE 1024 +#define AAD_SIZE 2 + byte *encrypted = (byte*)malloc(ENCRYPTED_BUFFER_SIZE + 16 + AAD_SIZE); + size_t payload_offset = 0; while (payload_offset < size) { size_t chunk_size = size - payload_offset; @@ -580,19 +582,21 @@ int client_send_encrypted_(client_context_t *context, x /= 256; } - size_t available = sizeof(encrypted) - 2; - int r = crypto_chacha20poly1305_encrypt(context->read_key, nonce, aead, 2, - payload + payload_offset, chunk_size, encrypted + 2, &available); + size_t available = ENCRYPTED_BUFFER_SIZE + 16; + int r = crypto_chacha20poly1305_encrypt(context->read_key, nonce, aead, AAD_SIZE, + payload + payload_offset, chunk_size, encrypted + AAD_SIZE, &available); if (r) { ERROR("Failed to chacha encrypt payload (code %d)", r); + free(encrypted); return -1; } payload_offset += chunk_size; - write(context, encrypted, available + 2); + write(context, encrypted, available + AAD_SIZE); } + free(encrypted); return 0; } @@ -616,8 +620,8 @@ int client_decrypt_(client_context_t *context, byte nonce[12]; memset(nonce, 0, sizeof(nonce)); - int payload_offset = 0; - int decrypted_offset = 0; + size_t payload_offset = 0; + size_t decrypted_offset = 0; while (payload_offset < payload_size) { size_t chunk_size = payload[payload_offset] + payload[payload_offset + 1] * 256; From 5f59512437e63be2382466bfff985cd4abe07bca Mon Sep 17 00:00:00 2001 From: David Kerr Date: Sat, 8 Jun 2024 11:27:01 -0400 Subject: [PATCH 17/34] Remove the keepalive call within write that causes crash, courtesy of @jgstroud --- src/arduino_homekit_server.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/arduino_homekit_server.cpp b/src/arduino_homekit_server.cpp index 80fbb15..c635a06 100644 --- a/src/arduino_homekit_server.cpp +++ b/src/arduino_homekit_server.cpp @@ -536,7 +536,8 @@ void write(client_context_t *context, byte *data, int data_size) { CLIENT_DEBUG(context, "Sending data of size %d", data_size); if (write_size != data_size) { context->error_write = true; - context->socket->keepAlive(1, 1, 1); // fast disconnected internally in 1 second. + //context->socket->keepAlive(1, 1, 1); // fast disconnected internally in 1 second. + context->socket->stop(); CLIENT_ERROR(context, "socket.write, data_size=%d, write_size=%d", data_size, write_size); } } From f968da11a5a5ba5dda3c760c7b81fbe64068224c Mon Sep 17 00:00:00 2001 From: David Kerr Date: Sat, 8 Jun 2024 11:29:48 -0400 Subject: [PATCH 18/34] Pairing can be very slow and sometimes iOS will send a TCP reset, courtesy of @jgstroud Attempt keep the session alive while pairing Add optimistic_yields to try and prevent the session from timing out --- src/arduino_homekit_server.cpp | 16 ++++++++++++---- src/wolfcrypt/src/integer.c | 2 +- src/wolfcrypt/src/srp.c | 4 ++++ 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/arduino_homekit_server.cpp b/src/arduino_homekit_server.cpp index c635a06..5325b08 100644 --- a/src/arduino_homekit_server.cpp +++ b/src/arduino_homekit_server.cpp @@ -3008,11 +3008,19 @@ client_context_t* homekit_server_accept_client(homekit_server_t *server) { wifiClient->localIP().toString().c_str(), wifiClient->localPort(), wifiClient->remoteIP().toString().c_str(), wifiClient->remotePort()); - wifiClient->keepAlive(HOMEKIT_SOCKET_KEEPALIVE_IDLE_SEC, - HOMEKIT_SOCKET_KEEPALIVE_INTERVAL_SEC, HOMEKIT_SOCKET_KEEPALIVE_IDLE_COUNT); wifiClient->setNoDelay(true); - wifiClient->setSync(false); - wifiClient->setTimeout(HOMEKIT_SOCKET_TIMEOUT); + wifiClient->setSync(true); + if (server->paired) { + wifiClient->keepAlive(HOMEKIT_SOCKET_KEEPALIVE_IDLE_SEC, + HOMEKIT_SOCKET_KEEPALIVE_INTERVAL_SEC, HOMEKIT_SOCKET_KEEPALIVE_IDLE_COUNT); + wifiClient->setTimeout(HOMEKIT_SOCKET_TIMEOUT); + INFO("Setting Timeout to 500ms"); + } else { + // During the pairing process, relax the session timeout and be more agressive about keepalives + wifiClient->keepAlive(5, 5, 20); + wifiClient->setTimeout(90000); + INFO("Setting Timeout to 90 s"); + } client_context_t *context = client_context_new(wifiClient); context->server = server; diff --git a/src/wolfcrypt/src/integer.c b/src/wolfcrypt/src/integer.c index be45d09..a8c7875 100644 --- a/src/wolfcrypt/src/integer.c +++ b/src/wolfcrypt/src/integer.c @@ -3535,7 +3535,7 @@ int s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode) * call `yield()` to run WiFi task, * to prevent WiFi disconnection while heavy crypto computing. */ - yield(); + optimistic_yield(1000); /* grab next digit as required */ if (--bitcnt == 0) { /* if digidx == -1 we are out of digits */ diff --git a/src/wolfcrypt/src/srp.c b/src/wolfcrypt/src/srp.c index 576b672..ee69dc5 100644 --- a/src/wolfcrypt/src/srp.c +++ b/src/wolfcrypt/src/srp.c @@ -647,6 +647,7 @@ int wc_SrpComputeKey(Srp* srp, byte* clientPubKey, word32 clientPubKeySz, r = mp_read_unsigned_bin(&temp1, srp->k, digestSz); if (!r) r = mp_iszero(&temp1) == MP_YES ? SRP_BAD_KEY_E : 0; if (!r) r = mp_exptmod(&srp->g, &srp->auth, &srp->N, &temp2); + optimistic_yield(1000); if (!r) r = mp_mulmod(&temp1, &temp2, &srp->N, &s); if (!r) r = mp_read_unsigned_bin(&temp2, serverPubKey, serverPubKeySz); if (!r) r = mp_iszero(&temp2) == MP_YES ? SRP_BAD_KEY_E : 0; @@ -659,10 +660,12 @@ int wc_SrpComputeKey(Srp* srp, byte* clientPubKey, word32 clientPubKeySz, /* secret = temp1 ^ temp2 % N */ if (!r) r = mp_exptmod(&temp1, &temp2, &srp->N, &s); + optimistic_yield(1000); } else if (!r && srp->side == SRP_SERVER_SIDE) { /* temp1 = v ^ u % N */ r = mp_exptmod(&srp->auth, &u, &srp->N, &temp1); + optimistic_yield(1000); /* temp2 = A * temp1 % N; rejects A == 0, A >= N */ if (!r) r = mp_read_unsigned_bin(&s, clientPubKey, clientPubKeySz); @@ -678,6 +681,7 @@ int wc_SrpComputeKey(Srp* srp, byte* clientPubKey, word32 clientPubKeySz, /* secret = temp2 * b % N */ if (!r) r = mp_exptmod(&temp2, &srp->priv, &srp->N, &s); + optimistic_yield(1000); } /* building session key from secret */ From e07e5e609372effc5ce2c897fe0d0643d2d45ce0 Mon Sep 17 00:00:00 2001 From: jgstroud Date: Sat, 16 Mar 2024 21:50:09 -0500 Subject: [PATCH 19/34] Set the ARDUINO_HOMEKIT_SKIP_ED25519_VERIFY flag (cherry picked from commit eab3d418eec1751bfc39170d7a9e7e85830ed978) --- src/user_settings.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/user_settings.h b/src/user_settings.h index 3b5e7d7..61114d5 100644 --- a/src/user_settings.h +++ b/src/user_settings.h @@ -7,7 +7,7 @@ //skip ed25519_verify, see crypto_ed25519_verify in crypto.c //Pair Verify Step 2/2: skip=35ms, not-skip=794ms -//#define ARDUINO_HOMEKIT_SKIP_ED25519_VERIFY +#define ARDUINO_HOMEKIT_SKIP_ED25519_VERIFY #include "stdint.h" #include "stddef.h" From 63607e61c21fdf02d1eb03324ed29c97186a7df5 Mon Sep 17 00:00:00 2001 From: jgstroud Date: Wed, 3 Apr 2024 21:00:40 -0500 Subject: [PATCH 20/34] Free up 512B of RAM in the http_parser (cherry picked from commit e85342a1a7022e8d4c2e8becf1fa7c46ec1cedb0) --- src/http_parser.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/http_parser.c b/src/http_parser.c index 252570b..528db8c 100644 --- a/src/http_parser.c +++ b/src/http_parser.c @@ -186,7 +186,7 @@ static const char *method_strings[] = * | "/" | "[" | "]" | "?" | "=" * | "{" | "}" | SP | HT */ -static const char tokens[256] = { +static const PROGMEM char tokens[256] = { /* 0 nul 1 soh 2 stx 3 etx 4 eot 5 enq 6 ack 7 bel */ 0, 0, 0, 0, 0, 0, 0, 0, /* 8 bs 9 ht 10 nl 11 vt 12 np 13 cr 14 so 15 si */ @@ -221,7 +221,7 @@ static const char tokens[256] = { 'x', 'y', 'z', 0, '|', 0, '~', 0 }; -static const int8_t unhex[256] = +static const PROGMEM char unhex[256] = {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 @@ -421,10 +421,10 @@ enum http_host_state (c) == ';' || (c) == ':' || (c) == '&' || (c) == '=' || (c) == '+' || \ (c) == '$' || (c) == ',') -#define STRICT_TOKEN(c) (tokens[(unsigned char)c]) +#define STRICT_TOKEN(c) (pgm_read_byte(tokens+c)) #if HTTP_PARSER_STRICT -#define TOKEN(c) (tokens[(unsigned char)c]) +#define TOKEN(c) (pgm_read_byte(tokens + c)) #define IS_URL_CHAR(c) (BIT_AT(normal_url_char, (unsigned char)c)) #define IS_HOST_CHAR(c) (IS_ALPHANUM(c) || (c) == '.' || (c) == '-') #else @@ -1937,7 +1937,7 @@ size_t http_parser_execute (http_parser *parser, assert(parser->nread == 1); assert(parser->flags & F_CHUNKED); - unhex_val = unhex[(unsigned char)ch]; + unhex_val = pgm_read_byte(unhex + ch); if (UNLIKELY(unhex_val == -1)) { SET_ERRNO(HPE_INVALID_CHUNK_SIZE); goto error; @@ -1959,7 +1959,7 @@ size_t http_parser_execute (http_parser *parser, break; } - unhex_val = unhex[(unsigned char)ch]; + unhex_val = pgm_read_byte(unhex + ch); if (unhex_val == -1) { if (ch == ';' || ch == ' ') { From 1bda7aaa783a15e3cf970531c7dda51fd3dc60ee Mon Sep 17 00:00:00 2001 From: David Kerr Date: Sat, 8 Jun 2024 11:34:19 -0400 Subject: [PATCH 21/34] Add function to close HomeKit server When performing a OTA firmware update, we need to shutdown the HomeKit sever because all network processing (including pings) stop during file uploads. So system cannot process incoming TCP requests, risking out-of-memory crashes as buffers fill up. --- src/arduino_homekit_server.cpp | 10 ++++++++++ src/arduino_homekit_server.h | 1 + 2 files changed, 11 insertions(+) diff --git a/src/arduino_homekit_server.cpp b/src/arduino_homekit_server.cpp index 5325b08..2becd98 100644 --- a/src/arduino_homekit_server.cpp +++ b/src/arduino_homekit_server.cpp @@ -3559,6 +3559,16 @@ void arduino_homekit_setup(homekit_server_config_t *config) { }); } +void arduino_homekit_close() { + if (homekit_mdns_started) { + homekit_mdns_started = false; + MDNS.close(); + } + if (running_server) { + server_free(running_server); + } +} + void arduino_homekit_loop() { if (homekit_mdns_started) { MDNS.update(); diff --git a/src/arduino_homekit_server.h b/src/arduino_homekit_server.h index 14d3367..0e318aa 100644 --- a/src/arduino_homekit_server.h +++ b/src/arduino_homekit_server.h @@ -226,6 +226,7 @@ typedef struct _client_event { void arduino_homekit_setup(homekit_server_config_t *config); +void arduino_homekit_close(); void arduino_homekit_loop(); homekit_server_t * arduino_homekit_get_running_server(); From 1a165d937c7c1777c0aedfcfbe631cd3c0c44747 Mon Sep 17 00:00:00 2001 From: David Kerr Date: Sat, 8 Jun 2024 11:34:47 -0400 Subject: [PATCH 22/34] Redirect log messages to RATGDO's custom logger function if LOG_MSG_BUFFER defined --- src/homekit_debug.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/homekit_debug.h b/src/homekit_debug.h index b09c631..fc52894 100644 --- a/src/homekit_debug.h +++ b/src/homekit_debug.h @@ -19,10 +19,17 @@ typedef unsigned char byte; #define HOMEKIT_LOG_DEBUG 3 #ifndef HOMEKIT_LOG_LEVEL -#define HOMEKIT_LOG_LEVEL HOMEKIT_NO_LOG +#define HOMEKIT_LOG_LEVEL HOMEKIT_LOG_INFO #endif +#ifdef LOG_MSG_BUFFER +// Added for RATGDO project that has custom logger function. +// Add -D LOG_MSG_BUFFER to compiler / platformio.ini +void logToBuffer_P(const char *fmt, ...); +#define HOMEKIT_PRINTF(message, ...) logToBuffer_P(PSTR(message), ##__VA_ARGS__) +#else #define HOMEKIT_PRINTF XPGM_PRINTF +#endif #if HOMEKIT_LOG_LEVEL >= HOMEKIT_LOG_DEBUG From bdab8c83b0d325a8beb4b326b5846d0bcdc9b2fc Mon Sep 17 00:00:00 2001 From: David Kerr Date: Sat, 8 Jun 2024 11:37:23 -0400 Subject: [PATCH 23/34] Update version number and repository URL --- library.json | 4 ++-- library.properties | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/library.json b/library.json index a1d67d8..651601d 100644 --- a/library.json +++ b/library.json @@ -10,9 +10,9 @@ "repository": { "type": "git", - "url": "https://github.com/Mixiaoxiao/Arduino-HomeKit-ESP8266.git" + "url": "https://github.com/cfurter/Arduino-HomeKit-ESP8266.git" }, - "version": "1.2.0", + "version": "1.5.0", "license": "MIT", "frameworks": "arduino", "platforms": "espressif8266", diff --git a/library.properties b/library.properties index 91be397..c866801 100644 --- a/library.properties +++ b/library.properties @@ -1,9 +1,9 @@ name=HomeKit-ESP8266 -version=1.2.0 +version=1.4.0 author=Mixiaoxiao maintainer=Mixiaoxiao sentence=Native Apple HomeKit accessory implementation for the ESP8266 Arduino core. paragraph=Native Apple HomeKit Accessory Implementation for the ESP8266 Arduino core. category=Communication -url=https://github.com/Mixiaoxiao/Arduino-HomeKit-ESP8266.git +url=https://github.com/cfurter/Arduino-HomeKit-ESP8266.git architectures=esp8266 From a5f0a124bf68e24da328b6eda5b7e5a70f9ebe6c Mon Sep 17 00:00:00 2001 From: David Kerr Date: Sat, 8 Jun 2024 11:55:51 -0400 Subject: [PATCH 24/34] Update README.md --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index 3d294f8..f61bedf 100644 --- a/README.md +++ b/README.md @@ -145,6 +145,13 @@ After memory optimization in v1.1.0: ## Change Log +#### v1.5.0 + +* Added function to close HomeKit server +* Moved some memory usage from stack to heap, and from heap to PROGMEM to reduce overall memory usage. +* Improved performance of HomeKit pairing, help avoid WiFi disconnection. +* Handle edge-case where client IP address may not be set during WiFi setup. + #### v1.4.0 * Add `yield()` while crypto computing, to prevent WiFi disconnection. The idea is from [BbIKTOP-issues80](https://github.com/Yurik72/ESPHap/issues/80#issuecomment-803685175) @@ -169,6 +176,7 @@ After memory optimization in v1.1.0: * Rename the `HTTP_METHOD`(s) in `http_parser.h` to avoid multi-definition errors when using `ESP8266WebServer` together. ## Thanks +* [homekit-ratgdo](https://github.com/ratgdo/homekit-ratgdo) * [esp-homekit](https://github.com/maximkulkin/esp-homekit) * [esp-homekit-demo](https://github.com/maximkulkin/esp-homekit-demo) * [esp_hw_wdt](https://github.com/ComSuite/esp_hw_wdt) From ce4e85ccfb336203d6754ed78363a3a56c764385 Mon Sep 17 00:00:00 2001 From: jgstroud Date: Sun, 16 Jun 2024 21:10:15 -0500 Subject: [PATCH 25/34] Memset the homekit value object. homekit_value_copy was failing on non-initialized value struct which results in inacurrate characterisitic updates --- src/types.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/types.c b/src/types.c index dbdcab9..63c8acf 100644 --- a/src/types.c +++ b/src/types.c @@ -6,6 +6,7 @@ homekit_value_t HOMEKIT_DEFAULT_CPP() { homekit_value_t homekit_value; + memset(&homekit_value, 0, sizeof(homekit_value_t)); //homekit_value.is_null = false;//该值为默认,不用设置 return homekit_value; } From 6ede919564093f3d61ca2d4eb94f7710c9dfdd40 Mon Sep 17 00:00:00 2001 From: jgstroud Date: Tue, 18 Jun 2024 12:29:54 -0500 Subject: [PATCH 26/34] Log characteristic value on update --- src/accessories.c | 40 ++++++++++++++++++++++++++++++++++ src/arduino_homekit_server.cpp | 22 +++++++++++++++++-- src/homekit/types.h | 1 + 3 files changed, 61 insertions(+), 2 deletions(-) diff --git a/src/accessories.c b/src/accessories.c index e360317..f6c5218 100644 --- a/src/accessories.c +++ b/src/accessories.c @@ -55,6 +55,46 @@ bool homekit_value_equal(homekit_value_t *a, homekit_value_t *b) { return false; } +//Call this function with a string pointer and be sure to free when done +void homekit_value_print(char** str, homekit_value_t *value) { + if (!value->is_null) { + switch (value->format) { + case homekit_format_bool: + asprintf(str, "%s", value->bool_value ? "True" : "False"); + break; + case homekit_format_uint8: + asprintf(str, "%u", value->uint8_value); + break; + case homekit_format_uint16: + asprintf(str, "%u", value->uint16_value); + break; + case homekit_format_uint32: + asprintf(str, "%u", value->uint32_value); + break; + case homekit_format_uint64: + asprintf(str, "%llu", value->uint64_value); + break; + case homekit_format_int: + asprintf(str, "%d", value->int_value); + break; + case homekit_format_float: + asprintf(str, "%f", value->float_value); + break; + case homekit_format_string: + asprintf(str, "%s", value->string_value); + break; + case homekit_format_tlv: + //TODO + case homekit_format_data: + //TODO + default: + asprintf(str, " "); + // unknown format + break; + } + } +} + void homekit_value_copy(homekit_value_t *dst, homekit_value_t *src) { memset(dst, 0, sizeof(*dst)); diff --git a/src/arduino_homekit_server.cpp b/src/arduino_homekit_server.cpp index 2becd98..5f83351 100644 --- a/src/arduino_homekit_server.cpp +++ b/src/arduino_homekit_server.cpp @@ -663,8 +663,12 @@ void client_notify_characteristic(homekit_characteristic_t *ch, homekit_value_t CLIENT_DEBUG(client, "This value is set by this client, no need to send notification"); return; } - CLIENT_INFO(client, "Got characteristic %d.%d change event", - ch->service->accessory->id, ch->id); + char * valstr; + homekit_value_print(&valstr, &value); + CLIENT_INFO(client, "Got characteristic %d.%d change event %s", + ch->service->accessory->id, ch->id, valstr); + free(valstr); + //DEBUG("Got characteristic %d.%d change event", ch->service->accessory->id, ch->id); if (!client->event_queue) { @@ -3049,6 +3053,14 @@ void homekit_server_process_notifications(homekit_server_t *server) { } characteristic_event_t *event = NULL; if (context->event_queue && q_pop(context->event_queue, &event)) { + #if HOMEKIT_LOG_LEVEL >= HOMEKIT_LOG_DEBUG + char * valstr; + homekit_value_print(&valstr, &event->value); + CLIENT_DEBUG(context, "Sending characteristic %d.%d change notification %s", + event->characteristic->service->accessory->id, event->characteristic->id, valstr); + free(valstr); + #endif + // Get and coalesce all client events client_event_t *events_head = (client_event_t*) malloc(sizeof(client_event_t)); events_head->characteristic = event->characteristic; @@ -3061,6 +3073,12 @@ void homekit_server_process_notifications(homekit_server_t *server) { client_event_t *events_tail = events_head; while (q_pop(context->event_queue, &event)) { + #if HOMEKIT_LOG_LEVEL >= HOMEKIT_LOG_DEBUG + homekit_value_print(&valstr, &event->value); + CLIENT_DEBUG(context, "Sending characteristic %d.%d change notification %s", + event->characteristic->service->accessory->id, event->characteristic->id, valstr); + free(valstr); + #endif //q_pop第二个参数必须传指针的地址 //event = context->event_queue->shift(); client_event_t *e = events_head; diff --git a/src/homekit/types.h b/src/homekit/types.h index e29718f..bb17f0d 100644 --- a/src/homekit/types.h +++ b/src/homekit/types.h @@ -105,6 +105,7 @@ typedef struct { } homekit_value_t; bool homekit_value_equal(homekit_value_t *a, homekit_value_t *b); +void homekit_value_print(char** str, homekit_value_t *value); void homekit_value_copy(homekit_value_t *dst, homekit_value_t *src); homekit_value_t *homekit_value_clone(homekit_value_t *value); void homekit_value_destruct(homekit_value_t *value); From 93ffa17fb58d0a2934e78a769e5adf4789070363 Mon Sep 17 00:00:00 2001 From: jgstroud Date: Fri, 28 Jun 2024 13:33:48 -0500 Subject: [PATCH 27/34] Clean up compiler warnings. Fix signed vs unsigned comparisons --- src/arduino_homekit_server.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/arduino_homekit_server.cpp b/src/arduino_homekit_server.cpp index 5f83351..5284c2e 100644 --- a/src/arduino_homekit_server.cpp +++ b/src/arduino_homekit_server.cpp @@ -572,7 +572,7 @@ int client_send_encrypted_(client_context_t *context, if (chunk_size > 1024) chunk_size = 1024; - byte aead[2] = { chunk_size % 256, chunk_size / 256 }; + byte aead[2] = { (byte)(chunk_size % 256), (byte)(chunk_size / 256) }; memcpy(encrypted, aead, 2); @@ -805,9 +805,9 @@ void send_tlv_response(client_context_t *context, tlv_values_t *values) { XPGM_BUFFCPY_STRING(char, http_headers, http_headers_pgm); - int response_size = strlen(http_headers) + payload_size + 32; + size_t response_size = strlen(http_headers) + payload_size + 32; char *response = (char*) malloc(response_size); - int response_len = snprintf(response, response_size, http_headers, payload_size); + size_t response_len = snprintf(response, response_size, http_headers, payload_size); if (response_size - response_len < payload_size + 1) { CLIENT_ERROR(context, "Incorrect response buffer size %d: headers took %d, payload size %d", @@ -877,13 +877,13 @@ void send_json_response(client_context_t *context, int status_code, byte *payloa break; } - int response_size = strlen(http_headers) + payload_size + strlen(status_text) + 32; + size_t response_size = strlen(http_headers) + payload_size + strlen(status_text) + 32; char *response = (char*) malloc(response_size); if (!response) { CLIENT_ERROR(context, "Failed to allocate response buffer of size %d", response_size); return; } - int response_len = snprintf(response, response_size, http_headers, status_code, status_text, + size_t response_len = snprintf(response, response_size, http_headers, status_code, status_text, payload_size); if (response_size - response_len < payload_size + 1) { @@ -2218,7 +2218,7 @@ HAPStatus process_characteristics_update(const cJSON *j_ch, client_context_t *co return HAPStatus_InvalidValue; } - int max_len = (ch->max_len) ? *ch->max_len : 64; + size_t max_len = (ch->max_len) ? *ch->max_len : 64; char *value = j_value->valuestring; if (strlen(value) > max_len) { @@ -2243,7 +2243,7 @@ HAPStatus process_characteristics_update(const cJSON *j_ch, client_context_t *co return HAPStatus_InvalidValue; } - int max_len = (ch->max_len) ? *ch->max_len : 256; + size_t max_len = (ch->max_len) ? *ch->max_len : 256; char *value = j_value->valuestring; size_t value_len = strlen(value); @@ -2295,7 +2295,7 @@ HAPStatus process_characteristics_update(const cJSON *j_ch, client_context_t *co // Default max data len = 2,097,152 but that does not make sense // for this accessory - int max_len = (ch->max_data_len) ? *ch->max_data_len : 4096; + size_t max_len = (ch->max_data_len) ? *ch->max_data_len : 4096; char *value = j_value->valuestring; size_t value_len = strlen(value); From 4966a84427d8e9567df09614b580e0b504c6232d Mon Sep 17 00:00:00 2001 From: David Kerr Date: Sun, 14 Jul 2024 17:08:43 -0400 Subject: [PATCH 28/34] log message timestamps should be unsigned long --- src/homekit_debug.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/homekit_debug.h b/src/homekit_debug.h index fc52894..7073996 100644 --- a/src/homekit_debug.h +++ b/src/homekit_debug.h @@ -36,7 +36,7 @@ void logToBuffer_P(const char *fmt, ...); #define DEBUG(message, ...) HOMEKIT_PRINTF(">>> %s: " message "\n", __func__, ##__VA_ARGS__) static uint32_t start_time = 0; #define DEBUG_TIME_BEGIN() start_time=millis(); -#define DEBUG_TIME_END(func_name) HOMEKIT_PRINTF("### [%7d] %s took %6dms\n", millis(), func_name, (millis() - start_time)); +#define DEBUG_TIME_END(func_name) HOMEKIT_PRINTF("### [%7lu] %s took %6lu ms\n", millis(), func_name, (millis() - start_time)); #define DEBUG_HEAP() DEBUG("Free heap: %d", system_get_free_heap_size()); #else @@ -50,7 +50,7 @@ static uint32_t start_time = 0; #if HOMEKIT_LOG_LEVEL >= HOMEKIT_LOG_ERROR -#define ERROR(message, ...) HOMEKIT_PRINTF("!!! [%7d] HomeKit: " message "\n", millis(), ##__VA_ARGS__) +#define ERROR(message, ...) HOMEKIT_PRINTF("!!! [%7lu] HomeKit: " message "\n", millis(), ##__VA_ARGS__) #else @@ -60,7 +60,7 @@ static uint32_t start_time = 0; #if HOMEKIT_LOG_LEVEL >= HOMEKIT_LOG_INFO -#define INFO(message, ...) HOMEKIT_PRINTF(">>> [%7d] HomeKit: " message "\n", millis(), ##__VA_ARGS__) +#define INFO(message, ...) HOMEKIT_PRINTF(">>> [%7lu] HomeKit: " message "\n", millis(), ##__VA_ARGS__) #define INFO_HEAP() INFO("Free heap: %d", system_get_free_heap_size()); #else From 426bc657efce195b222fcdd1bd8b066f18c3df4a Mon Sep 17 00:00:00 2001 From: David Kerr Date: Mon, 15 Jul 2024 17:39:00 -0400 Subject: [PATCH 29/34] Fix warning that /* used within /* block --- src/port.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/port.c b/src/port.c index f1c3d92..7fca56f 100644 --- a/src/port.c +++ b/src/port.c @@ -132,10 +132,9 @@ void homekit_mdns_add_txt(const char *key, const char *format, ...) { } void homekit_mdns_configure_finalize() { - /* - printf("mDNS announcement: Name=%s %s Port=%d TTL=%d\n", - name->value.string_value, txt_rec, PORT, 0); - */ -//}*/ + //printf("mDNS announcement: Name=%s %s Port=%d TTL=%d\n", + // name->value.string_value, txt_rec, PORT, 0); +} +*/ #endif From 2dc161b63279dfe0116673eb4c048708c7c85449 Mon Sep 17 00:00:00 2001 From: David Kerr Date: Mon, 15 Jul 2024 17:41:34 -0400 Subject: [PATCH 30/34] Fix warning .platformio/packages/framework-arduinoespressif8266/tools/sdk/lwip2/include/glue.h:98:37: warning: 'struct ip_info' declared inside parameter list will not be visible outside of this definition or declaration --- src/crypto.c | 2 ++ src/storage.c | 2 ++ src/watchdog.c | 2 ++ 3 files changed, 6 insertions(+) diff --git a/src/crypto.c b/src/crypto.c index ff7fbdd..bc7b909 100644 --- a/src/crypto.c +++ b/src/crypto.c @@ -9,6 +9,8 @@ #include #include +#include "lwipopts.h" // for struct ip_info warnting message... +//.platformio/packages/framework-arduinoespressif8266/tools/sdk/lwip2/include/glue.h:98:37: warning: 'struct ip_info' declared inside parameter list will not be visible outside of this definition or declaration #include "homekit_debug.h" #include "port.h" #include diff --git a/src/storage.c b/src/storage.c index 39d02d3..d60fe49 100644 --- a/src/storage.c +++ b/src/storage.c @@ -1,5 +1,7 @@ #include #include +#include "lwipopts.h" // for struct ip_info warnting message... +//.platformio/packages/framework-arduinoespressif8266/tools/sdk/lwip2/include/glue.h:98:37: warning: 'struct ip_info' declared inside parameter list will not be visible outside of this definition or declaration #include "constants.h" #include "pairing.h" #include "port.h" diff --git a/src/watchdog.c b/src/watchdog.c index 50823c1..e834bfe 100644 --- a/src/watchdog.c +++ b/src/watchdog.c @@ -6,6 +6,8 @@ * 2017 Alexander Epstine (a@epstine.com) */ +#include "lwipopts.h" // for struct ip_info warnting message... +//.platformio/packages/framework-arduinoespressif8266/tools/sdk/lwip2/include/glue.h:98:37: warning: 'struct ip_info' declared inside parameter list will not be visible outside of this definition or declaration #include "watchdog.h" #include "Arduino.h" #include "stdint.h" From 3f5401d012e164a88f1e0e92a44443eb6bf10665 Mon Sep 17 00:00:00 2001 From: David Kerr Date: Mon, 15 Jul 2024 18:05:22 -0400 Subject: [PATCH 31/34] declare functions to fix compiler warnings --- src/wolfcrypt/src/fe_low_mem.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/wolfcrypt/src/fe_low_mem.c b/src/wolfcrypt/src/fe_low_mem.c index 05a4b32..c8588cb 100644 --- a/src/wolfcrypt/src/fe_low_mem.c +++ b/src/wolfcrypt/src/fe_low_mem.c @@ -41,6 +41,10 @@ #include #endif +// Declare functions to avoid compiler warnings +void fprime_select(byte *dst, const byte *zero, const byte *one, byte condition); +void fe_select(byte *dst, const byte *zero, const byte *one,byte condition); + void fprime_copy(byte *x, const byte *a) { int i; From 5eb92fb4c2b2b9fc9fd934e48e80ad0f9d46d7e9 Mon Sep 17 00:00:00 2001 From: David Kerr Date: Mon, 15 Jul 2024 18:14:27 -0400 Subject: [PATCH 32/34] Fix warning that initializing const arrays with more elements than the declared size can hold. --- src/wolfcrypt/src/ge_low_mem.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/wolfcrypt/src/ge_low_mem.c b/src/wolfcrypt/src/ge_low_mem.c index 2a2fe80..54335f6 100644 --- a/src/wolfcrypt/src/ge_low_mem.c +++ b/src/wolfcrypt/src/ge_low_mem.c @@ -226,22 +226,22 @@ void sc_muladd(byte* out, const byte* a, const byte* b, const byte* c) const ge_p3 ed25519_base = { { 0x1a, 0xd5, 0x25, 0x8f, 0x60, 0x2d, 0x56, 0xc9, - 0xb2, 0xa7, 0x25, 0x95, 0x60, 0xc7, 0x2c, 0x69, - 0x5c, 0xdc, 0xd6, 0xfd, 0x31, 0xe2, 0xa4, 0xc0, - 0xfe, 0x53, 0x6e, 0xcd, 0xd3, 0x36, 0x69, 0x21 + 0xb2, 0xa7//, 0x25, 0x95, 0x60, 0xc7, 0x2c, 0x69, + //0x5c, 0xdc, 0xd6, 0xfd, 0x31, 0xe2, 0xa4, 0xc0, + //0xfe, 0x53, 0x6e, 0xcd, 0xd3, 0x36, 0x69, 0x21 }, { 0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, - 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, - 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, - 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66 + 0x66, 0x66//, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, + //0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, + //0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66 }, {1, 0}, { 0xa3, 0xdd, 0xb7, 0xa5, 0xb3, 0x8a, 0xde, 0x6d, - 0xf5, 0x52, 0x51, 0x77, 0x80, 0x9f, 0xf0, 0x20, - 0x7d, 0xe3, 0xab, 0x64, 0x8e, 0x4e, 0xea, 0x66, - 0x65, 0x76, 0x8b, 0xd7, 0x0f, 0x5f, 0x87, 0x67 + 0xf5, 0x52//, 0x51, 0x77, 0x80, 0x9f, 0xf0, 0x20, + //0x7d, 0xe3, 0xab, 0x64, 0x8e, 0x4e, 0xea, 0x66, + //0x65, 0x76, 0x8b, 0xd7, 0x0f, 0x5f, 0x87, 0x67 }, }; From 8db2d9b8cef6bb969cc6d4bee77f59a3101b2403 Mon Sep 17 00:00:00 2001 From: David Kerr Date: Mon, 15 Jul 2024 20:01:07 -0400 Subject: [PATCH 33/34] Fix incompatible type warnings by casting to the expected type. --- src/wolfcrypt/src/ge_low_mem.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/wolfcrypt/src/ge_low_mem.c b/src/wolfcrypt/src/ge_low_mem.c index 54335f6..2255485 100644 --- a/src/wolfcrypt/src/ge_low_mem.c +++ b/src/wolfcrypt/src/ge_low_mem.c @@ -306,13 +306,13 @@ void ed25519_add(ge_p3 *r, byte h[F25519_SIZE]; /* A = (Y1-X1)(Y2-X2) */ - lm_sub(c, p1->Y, p1->X); - lm_sub(d, p2->Y, p2->X); + lm_sub(c, (const byte *)p1->Y, (const byte *)p1->X); + lm_sub(d, (const byte *)p2->Y, (const byte *)p2->X); fe_mul__distinct(a, c, d); /* B = (Y1+X1)(Y2+X2) */ - lm_add(c, p1->Y, p1->X); - lm_add(d, p2->Y, p2->X); + lm_add(c, (const byte *)p1->Y, (const byte *)p1->X); + lm_add(d, (const byte *)p2->Y, (const byte *)p2->X); fe_mul__distinct(b, c, d); /* C = T1 k T2 */ @@ -388,7 +388,7 @@ void ed25519_double(ge_p3 *r, const ge_p3 *p) /* D = a A (alter sign) */ /* E = (X1+Y1)^2-A-B */ - lm_add(f, p->X, p->Y); + lm_add(f, (const byte *)p->X, (const byte *)p->Y); fe_mul__distinct(e, f, f); lm_sub(e, e, a); lm_sub(e, e, b); @@ -560,9 +560,9 @@ int ge_double_scalarmult_vartime_lowmem(ge_p2* R, const unsigned char *h, /* SB + -H(R,A,M)A */ ed25519_add(&A, &p, &A); - lm_copy(R->X, A.X); - lm_copy(R->Y, A.Y); - lm_copy(R->Z, A.Z); + lm_copy((byte *)R->X, (const byte *)A.X); + lm_copy((byte *)R->Y, (const byte *)A.Y); + lm_copy((byte *)R->Z, (const byte *)A.Z); return ret; } From ee1e0b793fb44285ebcb2e3fff18c8e7e50eb654 Mon Sep 17 00:00:00 2001 From: David Kerr Date: Mon, 15 Jul 2024 20:12:01 -0400 Subject: [PATCH 34/34] Fix warning on unused functions by enclosing the unused in the #ifdef of the functions that use them! --- src/wolfcrypt/src/ge_low_mem.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/wolfcrypt/src/ge_low_mem.c b/src/wolfcrypt/src/ge_low_mem.c index 2255485..3528259 100644 --- a/src/wolfcrypt/src/ge_low_mem.c +++ b/src/wolfcrypt/src/ge_low_mem.c @@ -45,6 +45,7 @@ void ed25519_add(ge_p3 *r, const ge_p3 *a, const ge_p3 *b); void ed25519_double(ge_p3 *r, const ge_p3 *a); +#if !defined(ESP_GE_DOUBLE_SCALARMULT_VARTIME_LOWMEM) static const byte ed25519_order[F25519_SIZE] = { 0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, @@ -68,7 +69,6 @@ static const word32 mu[33] = { 0xFF,0xFF,0xFF,0xFF,0x0F }; -#if !defined(ESP_GE_DOUBLE_SCALARMULT_VARTIME_LOWMEM) int ge_compress_key(byte* out, const byte* xIn, const byte* yIn, word32 keySz) @@ -90,7 +90,6 @@ int ge_compress_key(byte* out, const byte* xIn, const byte* yIn, (void)keySz; return 0; } -#endif /* ESP_GE_DOUBLE_SCALARMULT_VARTIME_LOWMEM */ static word32 lt(word32 a,word32 b) /* 16-bit inputs */ @@ -177,7 +176,6 @@ static void barrett_reduce(word32* r, word32 x[64]) reduce_add_sub(r); } -#if !defined(ESP_GE_DOUBLE_SCALARMULT_VARTIME_LOWMEM) void sc_reduce(unsigned char x[64]) { @@ -256,12 +254,14 @@ const ge_p3 ed25519_neutral = { }; +#if !defined(ESP_GE_DOUBLE_SCALARMULT_VARTIME_LOWMEM) static const byte ed25519_d[F25519_SIZE] = { 0xa3, 0x78, 0x59, 0x13, 0xca, 0x4d, 0xeb, 0x75, 0xab, 0xd8, 0x41, 0x41, 0x4d, 0x0a, 0x70, 0x00, 0x98, 0xe8, 0x79, 0x77, 0x79, 0x40, 0xc7, 0x8c, 0x73, 0xfe, 0x6f, 0x2b, 0xee, 0x6c, 0x03, 0x52 }; +#endif /* k = 2d */