diff --git a/src/arduino_homekit_server.cpp b/src/arduino_homekit_server.cpp index 7121914..6dcbb9f 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" @@ -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,28 +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.close(); MDNS.begin(name->value.string_value, staIP); INFO("MDNS restart: %s, IP: %s", name->value.string_value, staIP.toString().c_str()); MDNS.announce(); @@ -3176,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, @@ -3207,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); @@ -3255,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) @@ -3351,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/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 diff --git a/src/homekit_debug.h b/src/homekit_debug.h index d28b475..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_INFO +#define HOMEKIT_LOG_LEVEL HOMEKIT_NO_LOG #endif #define HOMEKIT_PRINTF XPGM_PRINTF diff --git a/src/storage.c b/src/storage.c index d6f69a7..40b893c 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,53 @@ 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() { - - 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 (!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); +} - char magic[sizeof(magic1)]; - memset(magic, 0, sizeof(magic)); +bool homekit_storage_set_magic() { + char magic[sizeof(hap_magic)]; + memcpy(magic, hap_magic, sizeof(magic)); - if (!spiflash_read(MAGIC_ADDR, (byte *)magic, sizeof(magic))) { - ERROR("Failed to read HomeKit storage magic"); + if (!spiflash_write(MAGIC_ADDR, (byte *)magic, sizeof(magic))) { + ERROR("Failed to write HomeKit storage magic"); + return false; } + return true; +} + +int homekit_storage_init() { + + 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 +146,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 +227,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 +259,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 +309,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 +335,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 +407,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 +434,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 +443,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();